1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

all: replace generic '<>' with '[]' in .vv files (#16593)

This commit is contained in:
yuyi 2022-12-05 22:32:15 +08:00 committed by GitHub
parent 7e9e2ff459
commit 50110d4c19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
90 changed files with 244 additions and 246 deletions

View File

@ -1,4 +1,4 @@
struct Item<T>{ struct Item[T]{
val T val T
} }

View File

@ -7,6 +7,6 @@ vlib/v/checker/tests/assign_generic_fn_err.vv:2:9: error: cannot assign generic
vlib/v/checker/tests/assign_generic_fn_err.vv:6:13: error: a non generic function called like a generic one vlib/v/checker/tests/assign_generic_fn_err.vv:6:13: error: a non generic function called like a generic one
4 | } 4 | }
5 | 5 |
6 | println(fun<int>(100)) 6 | println(fun[int](100))
| ~~~~~ | ~~~~~
7 | } 7 | }

View File

@ -3,5 +3,5 @@ fn main() {
return value return value
} }
println(fun<int>(100)) println(fun[int](100))
} }

View File

@ -7,7 +7,7 @@ vlib/v/checker/tests/cast_voidptr_to_struct_err.vv:6:9: error: cannot cast `void
8 | 8 |
vlib/v/checker/tests/cast_voidptr_to_struct_err.vv:10:9: error: cannot cast `voidptr` to struct vlib/v/checker/tests/cast_voidptr_to_struct_err.vv:10:9: error: cannot cast `voidptr` to struct
8 | 8 |
9 | fn unwrap_generic<T>(ptr voidptr) T { 9 | fn unwrap_generic[T](ptr voidptr) T {
10 | return T(ptr) 10 | return T(ptr)
| ~~~~~~ | ~~~~~~
11 | } 11 | }

View File

@ -6,13 +6,13 @@ fn unwrap_concrete(ptr voidptr) Foo {
return Foo(ptr) return Foo(ptr)
} }
fn unwrap_generic<T>(ptr voidptr) T { fn unwrap_generic[T](ptr voidptr) T {
return T(ptr) return T(ptr)
} }
pub fn main() { pub fn main() {
foo1 := unwrap_concrete(voidptr(0)) foo1 := unwrap_concrete(voidptr(0))
foo2 := unwrap_generic<Foo>(voidptr(0)) foo2 := unwrap_generic[Foo](voidptr(0))
println(foo1) println(foo1)
println(foo2) println(foo2)

View File

@ -3,12 +3,12 @@ struct Foo {
name string name string
} }
fn test<T>() { fn test[T]() {
mut t := T{} mut t := T{}
name := 'test' name := 'test'
t.$(name) = '3' t.$(name) = '3'
} }
fn main() { fn main() {
test<Foo>() test[Foo]()
} }

View File

@ -3,7 +3,7 @@ struct Foo {
name string name string
} }
fn test<T>() { fn test[T]() {
mut t := T{} mut t := T{}
$for f in T.fields { $for f in T.fields {
$if f.typ is string { $if f.typ is string {
@ -16,5 +16,5 @@ fn test<T>() {
} }
fn main() { fn main() {
test<Foo>() test[Foo]()
} }

View File

@ -8,7 +8,7 @@ fn unknown() {
_ = m _ = m
} }
fn gf<T>() { fn gf[T]() {
$for f in T.fields { $for f in T.fields {
$if f.typ is T {} $if f.typ is T {}
$if f.typ is U {} $if f.typ is U {}
@ -21,5 +21,5 @@ struct S1 {
} }
fn main() { fn main() {
gf<S1>() gf[S1]()
} }

View File

@ -1,13 +1,13 @@
vlib/v/checker/tests/fn_ref_arg_mismatch_err.vv:15:10: error: literal argument cannot be passed as reference parameter `&T` vlib/v/checker/tests/fn_ref_arg_mismatch_err.vv:15:10: error: literal argument cannot be passed as reference parameter `&T`
13 | fn main() { 13 | fn main() {
14 | foo := Foo<int>{} 14 | foo := Foo[int]{}
15 | foo.foo(12) 15 | foo.foo(12)
| ~~ | ~~
16 | 16 |
17 | bar<int>(12) 17 | bar[int](12)
vlib/v/checker/tests/fn_ref_arg_mismatch_err.vv:17:11: error: literal argument cannot be passed as reference parameter `&T` vlib/v/checker/tests/fn_ref_arg_mismatch_err.vv:17:11: error: literal argument cannot be passed as reference parameter `&T`
15 | foo.foo(12) 15 | foo.foo(12)
16 | 16 |
17 | bar<int>(12) 17 | bar[int](12)
| ~~ | ~~
18 | } 18 | }

View File

@ -1,18 +1,18 @@
module main module main
struct Foo<T> { } struct Foo[T] { }
fn (f &Foo<T>) foo(a &T) { fn (f &Foo[T]) foo(a &T) {
println(a) println(a)
} }
fn bar<T>(a &T) { fn bar[T](a &T) {
println(a) println(a)
} }
fn main() { fn main() {
foo := Foo<int>{} foo := Foo[int]{}
foo.foo(12) foo.foo(12)
bar<int>(12) bar[int](12)
} }

View File

@ -1,7 +1,7 @@
fn test(b bool) { fn test(b bool) {
} }
fn test2<T>(b bool, v T) { fn test2[T](b bool, v T) {
} }
fn main() { fn main() {

View File

@ -1,6 +1,6 @@
vlib/v/checker/tests/generic_closure_fn_decl_err.vv:5:2: error: generic closure fn must specify type parameter, e.g. fn [foo] [T]() vlib/v/checker/tests/generic_closure_fn_decl_err.vv:5:2: error: generic closure fn must specify type parameter, e.g. fn [foo] [T]()
3 | 3 |
4 | pub fn (mut app App) register<T>(service T) { 4 | pub fn (mut app App) register[T](service T) {
5 | fn [service] () { 5 | fn [service] () {
| ~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~
6 | println(service) 6 | println(service)

View File

@ -1,7 +1,7 @@
pub struct App { pub struct App {
} }
pub fn (mut app App) register<T>(service T) { pub fn (mut app App) register[T](service T) {
fn [service] () { fn [service] () {
println(service) println(service)
}() }()

View File

@ -1,7 +1,7 @@
vlib/v/checker/tests/generic_fn_decl_without_generic_names_err.vv:26:1: error: generic function declaration must specify generic type names vlib/v/checker/tests/generic_fn_decl_without_generic_names_err.vv:26:1: error: generic function declaration must specify generic type names
24 | } 24 | }
25 | 25 |
26 | fn g_worker(g Generic<T>) { 26 | fn g_worker(g Generic[T]) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~
27 | t := <-g.ch 27 | t := <-g.ch
28 | handle(t) 28 | handle(t)
@ -15,9 +15,9 @@ vlib/v/checker/tests/generic_fn_decl_without_generic_names_err.vv:32:1: error: g
34 | } 34 | }
Details: use `fn foo[T](x T) {`, not just `fn foo(x T) {` Details: use `fn foo[T](x T) {`, not just `fn foo(x T) {`
vlib/v/checker/tests/generic_fn_decl_without_generic_names_err.vv:40:1: error: generic method declaration must specify generic type names vlib/v/checker/tests/generic_fn_decl_without_generic_names_err.vv:40:1: error: generic method declaration must specify generic type names
38 | type MayBe<T> = None | T 38 | type MayBe[T] = None | T
39 | 39 |
40 | fn (m MayBe<T>) is_some() bool { 40 | fn (m MayBe[T]) is_some() bool {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
41 | return m is T 41 | return m is T
42 | } 42 | }

View File

@ -1,4 +1,4 @@
struct Generic<T> { struct Generic[T] {
ch chan T ch chan T
} }
@ -7,14 +7,14 @@ struct Concrete {
} }
fn main() { fn main() {
g := create_generic_t<Concrete>() g := create_generic_t[Concrete]()
g.ch <- Concrete{ g.ch <- Concrete{
msg: 'hello' msg: 'hello'
} }
} }
fn create_generic_t<T>() Generic<T> { fn create_generic_t[T]() Generic[T] {
g := Generic<T>{ g := Generic[T]{
ch: chan T{} ch: chan T{}
} }
@ -23,7 +23,7 @@ fn create_generic_t<T>() Generic<T> {
return g return g
} }
fn g_worker(g Generic<T>) { fn g_worker(g Generic[T]) {
t := <-g.ch t := <-g.ch
handle(t) handle(t)
// println("${t.msg}") // println("${t.msg}")
@ -35,8 +35,8 @@ fn handle(t T) {
struct None {} struct None {}
type MayBe<T> = None | T type MayBe[T] = None | T
fn (m MayBe<T>) is_some() bool { fn (m MayBe[T]) is_some() bool {
return m is T return m is T
} }

View File

@ -1,5 +1,5 @@
vlib/v/checker/tests/generic_infix_plus_err.vv:2:9: error: undefined operation `map[string]int` + `map[string]int` vlib/v/checker/tests/generic_infix_plus_err.vv:2:9: error: undefined operation `map[string]int` + `map[string]int`
1 | fn sum<T>(a T, b T) T { 1 | fn sum[T](a T, b T) T {
2 | return a + b 2 | return a + b
| ~~~~~ | ~~~~~
3 | } 3 | }

View File

@ -1,4 +1,4 @@
fn sum<T>(a T, b T) T { fn sum[T](a T, b T) T {
return a + b return a + b
} }

View File

@ -1,8 +1,8 @@
struct Struct<T> { struct Struct[T] {
value int value int
} }
interface Interface<T> { interface Interface[T] {
method() T method() T
} }

View File

@ -1,4 +1,4 @@
interface Output<T> { interface Output[T] {
val T val T
name string name string
} }

View File

@ -1,4 +1,4 @@
struct Just<T> { struct Just[T] {
value T value T
} }

View File

@ -1,7 +1,7 @@
vlib/v/checker/tests/generic_sumtype_decl_err_b.vv:7:6: error: generic sumtype `Maybe` must specify generic type names, e.g. Foo[T] vlib/v/checker/tests/generic_sumtype_decl_err_b.vv:7:6: error: generic sumtype `Maybe` must specify generic type names, e.g. Foo[T]
5 | struct Nothing {} 5 | struct Nothing {}
6 | 6 |
7 | type Maybe = Nothing | Just<T> 7 | type Maybe = Nothing | Just[T]
| ~~~~~ | ~~~~~
8 | 8 |
9 | fn main() { 9 | fn main() {

View File

@ -1,10 +1,10 @@
struct Just<T> { struct Just[T] {
value T value T
} }
struct Nothing {} struct Nothing {}
type Maybe = Nothing | Just<T> type Maybe = Nothing | Just[T]
fn main() { fn main() {
} }

View File

@ -1,7 +1,7 @@
vlib/v/checker/tests/generic_sumtype_decl_err_c.vv:7:27: error: generic type name `T` of generic struct `Just<T>` is not mentioned in sumtype `Maybe<B>` vlib/v/checker/tests/generic_sumtype_decl_err_c.vv:7:27: error: generic type name `T` of generic struct `Just<T>` is not mentioned in sumtype `Maybe<B>`
5 | struct Nothing {} 5 | struct Nothing {}
6 | 6 |
7 | type Maybe<B> = Nothing | Just<T> 7 | type Maybe[B] = Nothing | Just[T]
| ~~~~~~~ | ~~~~~~~
8 | 8 |
9 | fn main() { 9 | fn main() {

View File

@ -1,10 +1,10 @@
struct Just<T> { struct Just[T] {
value T value T
} }
struct Nothing {} struct Nothing {}
type Maybe<B> = Nothing | Just<T> type Maybe[B] = Nothing | Just[T]
fn main() { fn main() {
} }

View File

@ -1,20 +1,20 @@
import datatypes import datatypes
struct KeyVal<T> { struct KeyVal[T] {
key string key string
val T val T
} }
fn (a KeyVal<T>) == (b KeyVal<T>) bool { fn (a KeyVal[T]) == (b KeyVal[T]) bool {
return a.key == b.key return a.key == b.key
} }
fn (a KeyVal<T>) < (b KeyVal<T>) bool { fn (a KeyVal[T]) < (b KeyVal[T]) bool {
return a.key < b.key return a.key < b.key
} }
fn main() { fn main() {
mut bst := datatypes.BSTree<KeyVal<int>>{} mut bst := datatypes.BSTree[KeyVal[int]]{}
bst.insert(KeyVal<int>{key: "alibaba", val: 12}) bst.insert(KeyVal[int]{key: "alibaba", val: 12})
println(bst.in_order_traversal()) println(bst.in_order_traversal())
} }

View File

@ -1,13 +1,13 @@
interface List<T> { interface List[T] {
mut: mut:
add(e T) bool add(e T) bool
} }
struct LinkedList<T> { struct LinkedList[T] {
// ... // ...
} }
fn (mut list LinkedList<T>) add(e T) { fn (mut list LinkedList[T]) add(e T) {
// ... // ...
} }

View File

@ -1,27 +1,27 @@
vlib/v/checker/tests/generics_fn_called_arg_mismatch.vv:6:15: error: cannot use `int literal` as `bool` in argument 1 to `foo` vlib/v/checker/tests/generics_fn_called_arg_mismatch.vv:6:15: error: cannot use `int literal` as `bool` in argument 1 to `foo`
4 | 4 |
5 | fn main() { 5 | fn main() {
6 | foo<bool>(1) 6 | foo[bool](1)
| ^ | ^
7 | foo<bool>(2.2) 7 | foo[bool](2.2)
8 | foo<string>(true) 8 | foo[string](true)
vlib/v/checker/tests/generics_fn_called_arg_mismatch.vv:7:15: error: cannot use `float literal` as `bool` in argument 1 to `foo` vlib/v/checker/tests/generics_fn_called_arg_mismatch.vv:7:15: error: cannot use `float literal` as `bool` in argument 1 to `foo`
5 | fn main() { 5 | fn main() {
6 | foo<bool>(1) 6 | foo[bool](1)
7 | foo<bool>(2.2) 7 | foo[bool](2.2)
| ~~~ | ~~~
8 | foo<string>(true) 8 | foo[string](true)
9 | foo<int>('aaa') 9 | foo[int]('aaa')
vlib/v/checker/tests/generics_fn_called_arg_mismatch.vv:8:17: error: cannot use `bool` as `string` in argument 1 to `foo` vlib/v/checker/tests/generics_fn_called_arg_mismatch.vv:8:17: error: cannot use `bool` as `string` in argument 1 to `foo`
6 | foo<bool>(1) 6 | foo[bool](1)
7 | foo<bool>(2.2) 7 | foo[bool](2.2)
8 | foo<string>(true) 8 | foo[string](true)
| ~~~~ | ~~~~
9 | foo<int>('aaa') 9 | foo[int]('aaa')
10 | } 10 | }
vlib/v/checker/tests/generics_fn_called_arg_mismatch.vv:9:14: error: cannot use `string` as `int` in argument 1 to `foo` vlib/v/checker/tests/generics_fn_called_arg_mismatch.vv:9:14: error: cannot use `string` as `int` in argument 1 to `foo`
7 | foo<bool>(2.2) 7 | foo[bool](2.2)
8 | foo<string>(true) 8 | foo[string](true)
9 | foo<int>('aaa') 9 | foo[int]('aaa')
| ~~~~~ | ~~~~~
10 | } 10 | }

View File

@ -1,10 +1,10 @@
fn foo<T>(b T) { fn foo[T](b T) {
println(b) println(b)
} }
fn main() { fn main() {
foo<bool>(1) foo[bool](1)
foo<bool>(2.2) foo[bool](2.2)
foo<string>(true) foo[string](true)
foo<int>('aaa') foo[int]('aaa')
} }

View File

@ -1,7 +1,7 @@
vlib/v/checker/tests/generics_fn_called_fntype_arg_mismatch.vv:24:37: error: cannot use `fn (int) f64` as `fn (int) Point3D` in argument 2 to `new_array` vlib/v/checker/tests/generics_fn_called_fntype_arg_mismatch.vv:24:37: error: cannot use `fn (int) f64` as `fn (int) Point3D` in argument 2 to `new_array`
22 | println(good_cloud) 22 | println(good_cloud)
23 | // this should be a compilation error, because the function signature does not match: 23 | // this should be a compilation error, because the function signature does not match:
24 | bad_cloud := new_array<Point3D>(3, fn (idx int) f64 { 24 | bad_cloud := new_array[Point3D](3, fn (idx int) f64 {
| ~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~
25 | return 12345 25 | return 12345
26 | }) 26 | })

View File

@ -1,6 +1,6 @@
pub type FnArrayInit = fn (idx int) T pub type FnArrayInit = fn (idx int) T
pub fn new_array<T>(len int, initfn FnArrayInit<T>) []T { pub fn new_array[T](len int, initfn FnArrayInit[T]) []T {
mut res := []T{len: len} mut res := []T{len: len}
for idx in 0 .. res.len { for idx in 0 .. res.len {
res[idx] = initfn(idx) res[idx] = initfn(idx)
@ -16,12 +16,12 @@ struct Point3D {
fn main() { fn main() {
// this works as expected: // this works as expected:
good_cloud := new_array<Point3D>(3, fn (idx int) Point3D { good_cloud := new_array[Point3D](3, fn (idx int) Point3D {
return Point3D{idx, idx * 10, idx * -10} return Point3D{idx, idx * 10, idx * -10}
}) })
println(good_cloud) println(good_cloud)
// this should be a compilation error, because the function signature does not match: // this should be a compilation error, because the function signature does not match:
bad_cloud := new_array<Point3D>(3, fn (idx int) f64 { bad_cloud := new_array[Point3D](3, fn (idx int) f64 {
return 12345 return 12345
}) })
println(bad_cloud) println(bad_cloud)

View File

@ -1,9 +1,9 @@
struct Queue<T>{ struct Queue[T]{
buffer []T buffer []T
} }
fn new_queue<T>() Queue<T> { fn new_queue[T]() Queue[T] {
q := Queue<T>{ q := Queue[T]{
buffer: []T{cap: 1024} buffer: []T{cap: 1024}
} }
return q return q

View File

@ -1,6 +1,6 @@
vlib/v/checker/tests/generics_fn_called_outside_of_generic_fn.vv:4:2: error: generic fn using generic types cannot be called outside of generic fn vlib/v/checker/tests/generics_fn_called_outside_of_generic_fn.vv:4:2: error: generic fn using generic types cannot be called outside of generic fn
2 | 2 |
3 | fn main() { 3 | fn main() {
4 | foo<T>() 4 | foo[T]()
| ~~~~~~~~ | ~~~~~~~~
5 | } 5 | }

View File

@ -1,5 +1,5 @@
fn foo<T>() {} fn foo[T]() {}
fn main() { fn main() {
foo<T>() foo[T]()
} }

View File

@ -1,7 +1,7 @@
vlib/v/checker/tests/generics_fn_called_variadic_arg_mismatch.vv:12:16: error: cannot use `[]int` as `int` in argument 1 to `max` vlib/v/checker/tests/generics_fn_called_variadic_arg_mismatch.vv:12:16: error: cannot use `[]int` as `int` in argument 1 to `max`
10 | 10 |
11 | fn main() { 11 | fn main() {
12 | b := max<int>([1, 2, 3, 4]) 12 | b := max[int]([1, 2, 3, 4])
| ~~~~~~~~~~~~ | ~~~~~~~~~~~~
13 | println(b) 13 | println(b)
14 | } 14 | }

View File

@ -1,4 +1,4 @@
fn max<T>(a ...T) T { fn max[T](a ...T) T {
mut max := a[0] mut max := a[0]
for item in a[1..] { for item in a[1..] {
if max < item { if max < item {
@ -9,6 +9,6 @@ fn max<T>(a ...T) T {
} }
fn main() { fn main() {
b := max<int>([1, 2, 3, 4]) b := max[int]([1, 2, 3, 4])
println(b) println(b)
} }

View File

@ -1,12 +1,12 @@
vlib/v/checker/tests/generics_interface_decl_no_mention_err.vv:4:2: error: generic type name `T` is not mentioned in interface `Foo<U>` vlib/v/checker/tests/generics_interface_decl_no_mention_err.vv:4:2: error: generic type name `T` is not mentioned in interface `Foo<U>`
2 | 2 |
3 | interface Foo<U> { 3 | interface Foo[U] {
4 | Bar<T> 4 | Bar<T>
| ~~~ | ~~~
5 | foo(u U, p P) 5 | foo(u U, p P)
6 | bar(u U) []P 6 | bar(u U) []P
vlib/v/checker/tests/generics_interface_decl_no_mention_err.vv:5:13: error: generic type name `P` is not mentioned in interface `Foo<U>` vlib/v/checker/tests/generics_interface_decl_no_mention_err.vv:5:13: error: generic type name `P` is not mentioned in interface `Foo<U>`
3 | interface Foo<U> { 3 | interface Foo[U] {
4 | Bar<T> 4 | Bar<T>
5 | foo(u U, p P) 5 | foo(u U, p P)
| ^ | ^

View File

@ -1,10 +1,10 @@
fn main() {} fn main() {}
interface Foo<U> { interface Foo[U] {
Bar<T> Bar<T>
foo(u U, p P) foo(u U, p P)
bar(u U) []P bar(u U) []P
} }
interface Bar<T> { interface Bar[T] {
} }

View File

@ -12,18 +12,18 @@ pub mut:
z f64 z f64
} }
pub interface IComponentStore<T> { pub interface IComponentStore[T] {
mut: mut:
add(Entity, T) add(Entity, T)
} }
pub struct ComponentStore<T> { pub struct ComponentStore[T] {
pub mut: pub mut:
typ string typ string
// data etc // data etc
} }
pub fn (mut cs ComponentStore<T>) add(e Entity, value T) { pub fn (mut cs ComponentStore[T]) add(e Entity, value T) {
// index := cs.set.add(e.id) // index := cs.set.add(e.id)
// cs.instances[index] = value // cs.instances[index] = value
} }

View File

@ -14,6 +14,6 @@ fn main() {
r.node_create(mut g) r.node_create(mut g)
} }
pub fn (mut r Redis) node_create<T>(t T) bool { pub fn (mut r Redis) node_create[T](t T) bool {
return true return true
} }

View File

@ -1,7 +1,7 @@
vlib/v/checker/tests/generics_method_called_arg_mismatch.vv:3:15: error: cannot use `Foo` as `Bar` in argument 1 to `Obj.set` vlib/v/checker/tests/generics_method_called_arg_mismatch.vv:3:15: error: cannot use `Foo` as `Bar` in argument 1 to `Obj.set`
1 | fn main() { 1 | fn main() {
2 | mut obj := Obj{} 2 | mut obj := Obj{}
3 | obj.set<Bar>(Foo{}) 3 | obj.set[Bar](Foo{})
| ~~~~~ | ~~~~~
4 | } 4 | }
5 | 5 |

View File

@ -1,6 +1,6 @@
fn main() { fn main() {
mut obj := Obj{} mut obj := Obj{}
obj.set<Bar>(Foo{}) obj.set[Bar](Foo{})
} }
struct Foo {} struct Foo {}
@ -11,4 +11,4 @@ struct Bar {
struct Obj {} struct Obj {}
fn (mut o Obj) set<T>(val T) {} fn (mut o Obj) set[T](val T) {}

View File

@ -1,7 +1,7 @@
vlib/v/checker/tests/generics_method_called_variadic_arg_mismatch.vv:8:4: error: to pass `options` (string) to `req` (which accepts type `...string`), use `...options` vlib/v/checker/tests/generics_method_called_variadic_arg_mismatch.vv:8:4: error: to pass `options` (string) to `req` (which accepts type `...string`), use `...options`
6 | 6 |
7 | fn (c Client) products_list(options ...string) { 7 | fn (c Client) products_list(options ...string) {
8 | c.req<Product>(options) // (...options) works 8 | c.req[Product](options) // (...options) works
| ~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~
9 | } 9 | }
10 | 10 |

View File

@ -1,11 +1,11 @@
struct Client {} struct Client {}
fn (cl Client) req<T>(data ...string) {} fn (cl Client) req[T](data ...string) {}
struct Product {} struct Product {}
fn (c Client) products_list(options ...string) { fn (c Client) products_list(options ...string) {
c.req<Product>(options) // (...options) works c.req[Product](options) // (...options) works
} }
fn main() { fn main() {

View File

@ -1,4 +1,4 @@
struct Node<T> { struct Node[T] {
val T val T
name string name string
} }
@ -8,7 +8,7 @@ pub fn (x Node) str() string {
} }
fn main() { fn main() {
xx := Node<u16>{ xx := Node[u16]{
val: u16(11) val: u16(11)
name: 'man' name: 'man'
} }

View File

@ -2,9 +2,9 @@ module main
struct None {} struct None {}
pub type Maybe<T> = None | T pub type Maybe[T] = None | T
pub fn (m Maybe<T>) str<T>() string { pub fn (m Maybe[T]) str[T]() string {
return if m is T { return if m is T {
x := m as T x := m as T
'Some($x)' 'Some($x)'
@ -13,29 +13,29 @@ pub fn (m Maybe<T>) str<T>() string {
} }
} }
pub fn some<T>(v T) Maybe<T> { pub fn some[T](v T) Maybe[T] {
return Maybe<T>(v) return Maybe[T](v)
} }
pub fn noth<T>() Maybe<T> { pub fn noth[T]() Maybe[T] {
return Maybe<T>(None{}) return Maybe[T](None{})
} }
pub fn (m Maybe<T>) is_some<T>() bool { pub fn (m Maybe[T]) is_some[T]() bool {
return match m { return match m {
None { false } None { false }
T { true } T { true }
} }
} }
pub fn (m Maybe<T>) is_noth<T>() bool { pub fn (m Maybe[T]) is_noth[T]() bool {
return match m { return match m {
None { true } None { true }
T { false } T { false }
} }
} }
pub fn (m Maybe<T>) @or<T>(m2 Maybe<T>) Maybe<T> { pub fn (m Maybe[T]) @or[T](m2 Maybe[T]) Maybe[T] {
return match m { return match m {
None { None {
match m2 { match m2 {

View File

@ -1,14 +1,14 @@
vlib/v/checker/tests/generics_non_generic_struct_used_like_a_generic_one.vv:6:9: error: a non generic struct `Toy` used like a generic struct vlib/v/checker/tests/generics_non_generic_struct_used_like_a_generic_one.vv:6:9: error: a non generic struct `Toy` used like a generic struct
4 | 4 |
5 | fn get_toy1(toy Toy) Toy{ 5 | fn get_toy1(toy Toy) Toy{
6 | return Toy<T>{toy.toy_name} 6 | return Toy[T]{toy.toy_name}
| ~~~ | ~~~
7 | } 7 | }
8 | 8 |
vlib/v/checker/tests/generics_non_generic_struct_used_like_a_generic_one.vv:10:9: error: a non generic struct `Toy` used like a generic struct vlib/v/checker/tests/generics_non_generic_struct_used_like_a_generic_one.vv:10:9: error: a non generic struct `Toy` used like a generic struct
8 | 8 |
9 | fn get_toy2(toy Toy) Toy{ 9 | fn get_toy2(toy Toy) Toy{
10 | return Toy<T,U>{toy.toy_name} 10 | return Toy[T,U]{toy.toy_name}
| ~~~ | ~~~
11 | } 11 | }
12 | 12 |

View File

@ -3,11 +3,11 @@ struct Toy{
} }
fn get_toy1(toy Toy) Toy{ fn get_toy1(toy Toy) Toy{
return Toy<T>{toy.toy_name} return Toy[T]{toy.toy_name}
} }
fn get_toy2(toy Toy) Toy{ fn get_toy2(toy Toy) Toy{
return Toy<T,U>{toy.toy_name} return Toy[T,U]{toy.toy_name}
} }
fn main() { fn main() {

View File

@ -1,11 +1,11 @@
struct LL<T> { struct LL[T] {
mut: mut:
value T value T
next &LL = unsafe { 0 } next &LL = unsafe { 0 }
} }
fn main() { fn main() {
mut l := LL<int>{} mut l := LL[int]{}
l.value = 5 l.value = 5
println(l.value) println(l.value)
} }

View File

@ -1,6 +1,6 @@
vlib/v/checker/tests/generics_struct_in_non_generic_fn_err.vv:5:7: error: generic struct cannot be used in non-generic function vlib/v/checker/tests/generics_struct_in_non_generic_fn_err.vv:5:7: error: generic struct cannot be used in non-generic function
3 | 3 |
4 | fn main() { 4 | fn main() {
5 | _ := []Example<T>{} 5 | _ := []Example[T]{}
| ~~~~~~~~~~~~~ | ~~~~~~~~~~~~~
6 | } 6 | }

View File

@ -1,6 +1,6 @@
struct Example<T> { struct Example[T] {
} }
fn main() { fn main() {
_ := []Example<T>{} _ := []Example[T]{}
} }

View File

@ -1,7 +1,7 @@
vlib/v/checker/tests/generics_struct_type_mismatch_err.vv:7:20: error: the number of generic types of struct `Example` is inconsistent with the concrete types vlib/v/checker/tests/generics_struct_type_mismatch_err.vv:7:20: error: the number of generic types of struct `Example` is inconsistent with the concrete types
5 | 5 |
6 | fn main() { 6 | fn main() {
7 | example := Example<string>{ 7 | example := Example[string]{
| ~~~~~~~~ | ~~~~~~~~
8 | key: 'key' 8 | key: 'key'
9 | value: 'value' 9 | value: 'value'

View File

@ -1,10 +1,10 @@
struct Example<T, V> { struct Example[T, V] {
key T key T
value V value V
} }
fn main() { fn main() {
example := Example<string>{ example := Example[string]{
key: 'key' key: 'key'
value: 'value' value: 'value'
} }

View File

@ -1,6 +1,6 @@
vlib/v/checker/tests/generics_too_many_parameters.vv:6:8: error: expected 1 generic parameter, got 5 vlib/v/checker/tests/generics_too_many_parameters.vv:6:8: error: expected 1 generic parameter, got 5
4 | 4 |
5 | fn main() { 5 | fn main() {
6 | foo<bool, int, bool, bool, int>(1) 6 | foo[bool, int, bool, bool, int](1)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 | } 7 | }

View File

@ -1,7 +1,7 @@
fn foo<T>(b T) { fn foo[T](b T) {
println(b) println(b)
} }
fn main() { fn main() {
foo<bool, int, bool, bool, int>(1) foo[bool, int, bool, bool, int](1)
} }

View File

@ -1,8 +1,8 @@
fn test<T, B> (a T, b T, c B, d B) { fn test[T, B] (a T, b T, c B, d B) {
println("$a $b $c $d") println("$a $b $c $d")
} }
fn main() { fn main() {
test(2, 2, "2", 2) test(2, 2, "2", 2)
} }

View File

@ -1,13 +1,13 @@
vlib/v/checker/tests/incorrect_smartcast2_err.vv:24:9: notice: smartcast can only be used on the ident or selector, e.g. match foo, match foo.bar vlib/v/checker/tests/incorrect_smartcast2_err.vv:24:9: notice: smartcast can only be used on the ident or selector, e.g. match foo, match foo.bar
22 | 22 |
23 | fn doesntwork(v []Either<int, int>) { 23 | fn doesntwork(v []Either[int, int]) {
24 | match v[0] { 24 | match v[0] {
| ~~~ | ~~~
25 | Left<int> { 25 | Left[int] {
26 | println(v[0].error) 26 | println(v[0].error)
vlib/v/checker/tests/incorrect_smartcast2_err.vv:26:17: error: field `error` does not exist or have the same type in all sumtype variants vlib/v/checker/tests/incorrect_smartcast2_err.vv:26:17: error: field `error` does not exist or have the same type in all sumtype variants
24 | match v[0] { 24 | match v[0] {
25 | Left<int> { 25 | Left[int] {
26 | println(v[0].error) 26 | println(v[0].error)
| ~~~~~ | ~~~~~
27 | } 27 | }

View File

@ -1,28 +1,28 @@
struct Left<E> { struct Left[E] {
error E error E
} }
struct Right<T> { struct Right[T] {
inner T inner T
} }
type Either<T, E> = type Either[T, E] =
Left<E> | Left[E] |
Right<T> Right[T]
fn works(v []Either<int, int>) { fn works(v []Either[int, int]) {
first := v[0] first := v[0]
match first { match first {
Left<int> { Left[int] {
println(first.error) println(first.error)
} }
else {} else {}
} }
} }
fn doesntwork(v []Either<int, int>) { fn doesntwork(v []Either[int, int]) {
match v[0] { match v[0] {
Left<int> { Left[int] {
println(v[0].error) println(v[0].error)
} }
else {} else {}

View File

@ -1,4 +1,4 @@
struct Item<T>{ struct Item[T]{
val T val T
} }

View File

@ -1,6 +1,6 @@
struct Data {} struct Data {}
fn (_ Data) func<T>() T { fn (_ Data) func[T]() T {
return T{} return T{}
} }

View File

@ -5,7 +5,7 @@ fn foo() ? {
println('foo is called') println('foo is called')
} }
fn bar<T>(v T) ?T { fn bar[T](v T) ?T {
return none return none
} }

View File

@ -1,5 +1,5 @@
vlib/v/checker/tests/struct_field_with_default_err.vv:2:22: error: unknown struct `T` vlib/v/checker/tests/struct_field_with_default_err.vv:2:22: error: unknown struct `T`
1 | struct Dummy<T> { 1 | struct Dummy[T] {
2 | arbitrary_field T = T{} 2 | arbitrary_field T = T{}
| ~~~ | ~~~
3 | } 3 | }

View File

@ -1,4 +1,4 @@
struct Dummy<T> { struct Dummy[T] {
arbitrary_field T = T{} arbitrary_field T = T{}
} }

View File

@ -1,7 +1,7 @@
vlib/v/checker/tests/type_alias_struct_generic_unknown_name_err.vv:7:16: error: unknown type `UnknownType` vlib/v/checker/tests/type_alias_struct_generic_unknown_name_err.vv:7:16: error: unknown type `UnknownType`
5 | } 5 | }
6 | 6 |
7 | type NewType = Foo<UnknownType> 7 | type NewType = Foo[UnknownType]
| ~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~
8 | 8 |
9 | fn main() { 9 | fn main() {

View File

@ -1,10 +1,10 @@
module main module main
struct Foo<T> { struct Foo[T] {
value T value T
} }
type NewType = Foo<UnknownType> type NewType = Foo[UnknownType]
fn main() { fn main() {
} }

View File

@ -1,7 +1,7 @@
vlib/v/checker/tests/unknown_generic_type.vv:6:13: error: unknown type `Foo` vlib/v/checker/tests/unknown_generic_type.vv:6:13: error: unknown type `Foo`
4 | 4 |
5 | fn main() { 5 | fn main() {
6 | x := decode<Foo>('{"name": "test"}')? 6 | x := decode[Foo]('{"name": "test"}')?
| ~~~~~ | ~~~~~
7 | println(x) 7 | println(x)
8 | } 8 | }

View File

@ -1,8 +1,8 @@
fn decode<T>(raw_data string) ?T { fn decode[T](raw_data string) ?T {
return none return none
} }
fn main() { fn main() {
x := decode<Foo>('{"name": "test"}')? x := decode[Foo]('{"name": "test"}')?
println(x) println(x)
} }

View File

@ -54,8 +54,8 @@ fn (s Struct) method(v StructMethodArg) StructMethodRet {
return StructMethodRet{} return StructMethodRet{}
} }
fn (s Struct) method_generic<T>(v StructMethodArgGeneric<T>) StructMethodRetGeneric<T> { fn (s Struct) method_generic[T](v StructMethodArgGeneric[T]) StructMethodRetGeneric[T] {
return StructMethodRet<T>{} return StructMethodRet[T]{}
} }
interface Interface { interface Interface {
@ -74,8 +74,8 @@ fn f(v FnArg) FnRet {
fn f2(v Generic<FnArgTypeParam1, FnArgTypeParam2>) Generic<FnRetTypeParam1, FnRetTypeParam2> {} fn f2(v Generic<FnArgTypeParam1, FnArgTypeParam2>) Generic<FnRetTypeParam1, FnRetTypeParam2> {}
fn f_generic<T>(v FnArgGeneric<T>) FnRetGeneric<T> { fn f_generic[T](v FnArgGeneric[T]) FnRetGeneric[T] {
return FnRetGeneric<T>{} return FnRetGeneric[T]{}
} }
struct App { struct App {

View File

@ -4,31 +4,31 @@ struct Token {}
struct ParseErr {} struct ParseErr {}
type Opt<T> = None<T> | Some<T> type Opt[T] = None[T] | Some[T]
struct None<T> {} struct None[T] {}
struct Some<T> { struct Some[T] {
value T value T
} }
type Result<T, U> = Err<U> | Ok<T> type Result[T, U] = Err[U] | Ok[T]
struct Ok<T> { struct Ok[T] {
value T value T
} }
struct Err<U> { struct Err[U] {
value U value U
} }
fn main() { fn main() {
r := Opt<ParseRes>(None<ParseRes>{}) r := Opt[ParseRes](None[ParseRes]{})
match r { match r {
Some<ParseRes> { Some[ParseRes] {
// make possible cast fo the same type! // make possible cast fo the same type!
rx := Result<[]Token, ParseErr>(r.value) rx := Result[[]Token, ParseErr](r.value)
} }
None<ParseRes> {} None[ParseRes] {}
} }
} }

View File

@ -1,7 +1,7 @@
vlib/v/parser/tests/fn_param_name_cap.vv:6:9: error: parameter name must not begin with upper case letter (`T`) vlib/v/parser/tests/fn_param_name_cap.vv:5:9: error: parameter name must not begin with upper case letter (`T`)
4 | fn f(Type) 3 | fn f(Type)
5 | 4 |
6 | fn g<T>(T v) { 5 | fn g[T](T v) {
| ^ | ^
7 | 6 | }
8 | } 7 |

View File

@ -1,10 +1,8 @@
type Type = int type Type = int
// OK
fn f(Type) fn f(Type)
fn g<T>(T v) { fn g[T](T v) {
} }
g(5) g(5)

View File

@ -1,7 +1,7 @@
vlib/v/parser/tests/generic_struct_parameter_err.vv:10:17: error: the parameter type name of a generic struct, must be a single capital letter placeholder name, like T or X, or a non-generic type name like int, string, etc. vlib/v/parser/tests/generic_struct_parameter_err.vv:10:17: error: the parameter type name of a generic struct, must be a single capital letter placeholder name, like T or X, or a non-generic type name like int, string, etc.
8 | struct MyContainer<T> { 8 | struct MyContainer[T] {
9 | mut: 9 | mut:
10 | lst LinkedList<MyNode<T>> 10 | lst LinkedList[MyNode[T]]
| ~~~~~~~~~ | ~~~~~~~~~
11 | } 11 | }
12 | 12 |

View File

@ -1,23 +1,23 @@
import datatypes { LinkedList } import datatypes { LinkedList }
struct MyNode<T> { struct MyNode[T] {
mut: mut:
data T data T
} }
struct MyContainer<T> { struct MyContainer[T] {
mut: mut:
lst LinkedList<MyNode<T>> lst LinkedList[MyNode[T]]
} }
fn (mut c MyContainer<T>) push(data T) { fn (mut c MyContainer[T]) push(data T) {
node := MyNode<T>{ node := MyNode[T]{
data: data data: data
} }
c.lst.push<T>(node) c.lst.push[T](node)
} }
fn main() { fn main() {
mut c := MyContainer<string>{} mut c := MyContainer[string]{}
println(c) println(c)
} }

View File

@ -1,5 +1,5 @@
vlib/v/parser/tests/generic_struct_receiver_nested_generic_err.vv:5:11: error: the parameter type name of a generic struct, must be a single capital letter placeholder name, like T or X, or a non-generic type name like int, string, etc. vlib/v/parser/tests/generic_struct_receiver_nested_generic_err.vv:5:11: error: the parameter type name of a generic struct, must be a single capital letter placeholder name, like T or X, or a non-generic type name like int, string, etc.
3 | } 3 | }
4 | 4 |
5 | fn (a Foo<Foo<T>>) baz() {} 5 | fn (a Foo[Foo[T]]) baz() {}
| ~~~~~~ | ~~~~~~

View File

@ -1,5 +1,5 @@
struct Foo<T> { struct Foo[T] {
bar T bar T
} }
fn (a Foo<Foo<T>>) baz() {} fn (a Foo[Foo[T]]) baz() {}

View File

@ -1,7 +1,7 @@
vlib/v/parser/tests/generic_struct_type_using_multi_return_err.vv:6:18: error: cannot use multi return as generic concrete type vlib/v/parser/tests/generic_struct_type_using_multi_return_err.vv:6:18: error: cannot use multi return as generic concrete type
4 | 4 |
5 | fn main() { 5 | fn main() {
6 | sample := Tuple<(int, int)>{} 6 | sample := Tuple[(int, int)]{}
| ~~~~~~~~~~ | ~~~~~~~~~~
7 | println(sample) 7 | println(sample)
8 | } 8 | }

View File

@ -1,8 +1,8 @@
struct Tuple<T> { struct Tuple[T] {
data T data T
} }
fn main() { fn main() {
sample := Tuple<(int, int)>{} sample := Tuple[(int, int)]{}
println(sample) println(sample)
} }

View File

@ -1,3 +1,3 @@
vlib/v/parser/tests/generic_type_alias_decl.vv:1:1: error: generic type aliases are not yet implemented vlib/v/parser/tests/generic_type_alias_decl.vv:1:1: error: generic type aliases are not yet implemented
1 | type Pointer<T> = &T 1 | type Pointer[T] = &T
| ~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~

View File

@ -1 +1 @@
type Pointer<T> = &T type Pointer[T] = &T

View File

@ -7,6 +7,6 @@ fn main() {
do(mut r) do(mut r)
} }
pub fn do<T>(mut t T) { pub fn do[T](mut t T) {
dump(t) dump(t)
} }

View File

@ -32,7 +32,7 @@ fn main() {
run(&mi) run(&mi)
} }
fn run<T>(in_put T) { fn run[T](in_put T) {
dump(in_put.in_()) dump(in_put.in_())
dump(in_put.out()) dump(in_put.out())
$if T is InOut { $if T is InOut {

View File

@ -10,19 +10,19 @@ pub fn (s &Score) ave() f64 {
return s.ave return s.ave
} }
fn next<T>(input T) f64 { fn next[T](input T) f64 {
$if T is Average { $if T is Average {
dump('${T.name} $input') dump('${T.name} $input')
ret := next2<T>(input) ret := next2[T](input)
return ret return ret
} $else { } $else {
dump('${T.name} $input') dump('${T.name} $input')
ret := next2<T>(input) ret := next2[T](input)
return ret return ret
} }
} }
fn next2<T>(input T) f64 { fn next2[T](input T) f64 {
dump('${T.name} $input') dump('${T.name} $input')
$if T is Average { $if T is Average {
return input.ave() return input.ave()

View File

@ -6,7 +6,7 @@ fn main() {
func(mut b) func(mut b)
} }
fn func<T>(mut t T) { fn func[T](mut t T) {
$if T is $Array { $if T is $Array {
for i in 0 .. t.len { for i in 0 .. t.len {
println(t[i]) println(t[i])

View File

@ -1,10 +1,10 @@
module main module main
fn shuffle_impl<T>(mut a []T) ? { fn shuffle_impl[T](mut a []T) ? {
println('FN: ${@FN:20} | T: ${typeof(a).name}') println('FN: ${@FN:20} | T: ${typeof(a).name}')
} }
fn shuffle<T>(mut a []T) ? { fn shuffle[T](mut a []T) ? {
println('FN: ${@FN:20} | T: ${typeof(a).name}') println('FN: ${@FN:20} | T: ${typeof(a).name}')
shuffle_impl(mut a)? shuffle_impl(mut a)?
} }

View File

@ -3,7 +3,7 @@ fn main() {
proc(c) proc(c)
} }
fn proc<T>(input T) { fn proc[T](input T) {
$if T is &u8 { $if T is &u8 {
println('T is $T.name') println('T is $T.name')
} }

View File

@ -2,30 +2,30 @@ type ParseRes = Result<[]Token, ParseErr>
struct ParseErr {} struct ParseErr {}
type Opt<T> = None<T> | Some<T> type Opt[T] = None[T] | Some[T]
struct None<T> {} struct None[T] {}
struct Some<T> { struct Some[T] {
value T value T
} }
type Result<T, U> = Err<U> | Ok<T> type Result[T, U] = Err[U] | Ok[T]
struct Ok<T> { struct Ok[T] {
value T value T
} }
struct Err<U> { struct Err[U] {
value U value U
} }
fn test_report() { fn test_report() {
r := Opt<ParseRes>(None<ParseRes>{}) r := Opt[ParseRes](None[ParseRes]{})
match r { match r {
Some<ParseRes> { Some[ParseRes] {
rx := Result<[]Token, ParseErr>(r.value) rx := Result[[]Token, ParseErr](r.value)
} }
None<ParseRes> {} None[ParseRes] {}
} }
} }

View File

@ -7,7 +7,7 @@ struct TypeA {}
struct TypeB {} struct TypeB {}
fn (mut c Calc<S>) next<T>(input T) f64 { fn (mut c Calc<S>) next[T](input T) f64 {
$if S is TypeA || S is TypeB { $if S is TypeA || S is TypeB {
return c.typ.next(input) return c.typ.next(input)
} $else { } $else {
@ -15,21 +15,21 @@ fn (mut c Calc<S>) next<T>(input T) f64 {
} }
} }
fn (mut t TypeA) next<T>(input T) f64 { fn (mut t TypeA) next[T](input T) f64 {
return 10 return 10
} }
fn (mut t TypeB) next<T>(input T) f64 { fn (mut t TypeB) next[T](input T) f64 {
return 11 return 11
} }
fn new<S>() Calc<S> { fn new[S]() Calc[S] {
$if S is TypeA { $if S is TypeA {
return Calc<TypeA>{ return Calc[TypeA]{
typ: TypeA{} typ: TypeA{}
} }
} $else $if S is TypeB { } $else $if S is TypeB {
return Calc<TypeB>{ return Calc[TypeB]{
typ: TypeB{} typ: TypeB{}
} }
} $else { } $else {
@ -39,13 +39,13 @@ fn new<S>() Calc<S> {
fn main() { fn main() {
{ {
mut c := Calc<TypeA>{ mut c := Calc[TypeA]{
typ: TypeA{} typ: TypeA{}
} }
assert c.next(100) == 10.0 assert c.next(100) == 10.0
} }
{ {
mut c := Calc<TypeB>{ mut c := Calc[TypeB]{
typ: TypeB{} typ: TypeB{}
} }
assert c.next(100) == 11.0 assert c.next(100) == 11.0

View File

@ -13,7 +13,7 @@ mut:
fn test_json_decode_fails_to_decode_unrecognised_array_of_dicts() { fn test_json_decode_fails_to_decode_unrecognised_array_of_dicts() {
data := '[{"twins":[{"id":123,"seed":"abcde","pubkey":"xyzasd"},{"id":456,"seed":"dfgdfgdfgd","pubkey":"skjldskljh45sdf"}]}]' data := '[{"twins":[{"id":123,"seed":"abcde","pubkey":"xyzasd"},{"id":456,"seed":"dfgdfgdfgd","pubkey":"skjldskljh45sdf"}]}]'
json.decode<TestTwins>(data) or { json.decode[TestTwins](data) or {
assert err.msg() == "expected field 'twins' is missing" assert err.msg() == "expected field 'twins' is missing"
return return
} }
@ -22,7 +22,7 @@ fn test_json_decode_fails_to_decode_unrecognised_array_of_dicts() {
fn test_json_decode_works_with_a_dict_of_arrays() { fn test_json_decode_works_with_a_dict_of_arrays() {
data := '{"twins":[{"id":123,"seed":"abcde","pubkey":"xyzasd"},{"id":456,"seed":"dfgdfgdfgd","pubkey":"skjldskljh45sdf"}]}' data := '{"twins":[{"id":123,"seed":"abcde","pubkey":"xyzasd"},{"id":456,"seed":"dfgdfgdfgd","pubkey":"skjldskljh45sdf"}]}'
res := json.decode<TestTwins>(data) or { res := json.decode[TestTwins](data) or {
assert false assert false
exit(1) exit(1)
} }
@ -40,7 +40,7 @@ struct Mount {
fn test_decode_u64() { fn test_decode_u64() {
data := '{"size": 10737418240}' data := '{"size": 10737418240}'
m := json.decode<Mount>(data)! m := json.decode[Mount](data)!
assert m.size == 10737418240 assert m.size == 10737418240
// println(m) // println(m)
} }
@ -64,7 +64,7 @@ mut:
fn test_skip_fields_should_be_initialised_by_json_decode() { fn test_skip_fields_should_be_initialised_by_json_decode() {
data := '{"total_comments": 55, "id": 123}' data := '{"total_comments": 55, "id": 123}'
mut task := json.decode<Task>(data)! mut task := json.decode[Task](data)!
assert task.id == 123 assert task.id == 123
assert task.total_comments == 55 assert task.total_comments == 55
assert task.comments == [] assert task.comments == []
@ -79,7 +79,7 @@ struct DbConfig {
} }
fn test_decode_error_message_should_have_enough_context_empty() { fn test_decode_error_message_should_have_enough_context_empty() {
json.decode<DbConfig>('') or { json.decode[DbConfig]('') or {
assert err.msg().len < 2 assert err.msg().len < 2
return return
} }
@ -87,7 +87,7 @@ fn test_decode_error_message_should_have_enough_context_empty() {
} }
fn test_decode_error_message_should_have_enough_context_just_brace() { fn test_decode_error_message_should_have_enough_context_just_brace() {
json.decode<DbConfig>('{') or { json.decode[DbConfig]('{') or {
assert err.msg() == '{' assert err.msg() == '{'
return return
} }
@ -100,7 +100,7 @@ fn test_decode_error_message_should_have_enough_context_trailing_comma_at_end()
"dbname": "alex", "dbname": "alex",
"user": "alex", "user": "alex",
}' }'
json.decode<DbConfig>(txt) or { json.decode[DbConfig](txt) or {
assert err.msg() == ' "user": "alex",\n}' assert err.msg() == ' "user": "alex",\n}'
return return
} }
@ -109,7 +109,7 @@ fn test_decode_error_message_should_have_enough_context_trailing_comma_at_end()
fn test_decode_error_message_should_have_enough_context_in_the_middle() { fn test_decode_error_message_should_have_enough_context_in_the_middle() {
txt := '{"host": "localhost", "dbname": "alex" "user": "alex", "port": "1234"}' txt := '{"host": "localhost", "dbname": "alex" "user": "alex", "port": "1234"}'
json.decode<DbConfig>(txt) or { json.decode[DbConfig](txt) or {
assert err.msg() == 'ost", "dbname": "alex" "user":' assert err.msg() == 'ost", "dbname": "alex" "user":'
return return
} }

View File

@ -6,7 +6,7 @@ struct TodoDto {
fn test_decode_with_encode_arg() { fn test_decode_with_encode_arg() {
body := TodoDto{} body := TodoDto{}
ret := json.decode<TodoDto>(json.encode(body))! ret := json.decode[TodoDto](json.encode(body))!
println(ret) println(ret)
assert ret.foo == 0 assert ret.foo == 0
} }

View File

@ -1,6 +1,6 @@
import x.json2 as json import x.json2 as json
struct Result<T> { struct Result[T] {
ok bool ok bool
result T result T
} }
@ -10,14 +10,14 @@ struct User {
username string username string
} }
fn func<T>() !T { fn func[T]() !T {
text := '{"ok": true, "result":{"id":37467243, "username": "ciao"}}' text := '{"ok": true, "result":{"id":37467243, "username": "ciao"}}'
a := json.decode<Result<T>>(text)! a := json.decode[Result[T]](text)!
return a.result return a.result
} }
fn test_decode_with_generic_struct() { fn test_decode_with_generic_struct() {
ret := func<User>()! ret := func[User]()!
println(ret) println(ret)
assert ret.id == 37467243 assert ret.id == 37467243
assert ret.username == 'ciao' assert ret.username == 'ciao'

View File

@ -282,7 +282,7 @@ fn test_nested_type() {
} }
} }
struct Foo<T> { struct Foo[T] {
pub: pub:
name string name string
data T data T
@ -290,10 +290,10 @@ pub:
//! BUGFIX - .from_json(res) //! BUGFIX - .from_json(res)
fn test_generic_struct() { fn test_generic_struct() {
foo_int := Foo<int>{'bar', 12} foo_int := Foo[int]{'bar', 12}
foo_enc := json.encode(foo_int) foo_enc := json.encode(foo_int)
assert foo_enc == '{"name":"bar","data":12}' assert foo_enc == '{"name":"bar","data":12}'
foo_dec := json.decode<Foo<int>>(foo_enc)! foo_dec := json.decode[Foo[int]](foo_enc)!
assert foo_dec.name == 'bar' assert foo_dec.name == 'bar'
assert foo_dec.data == 12 assert foo_dec.data == 12
} }
@ -302,7 +302,7 @@ fn test_generic_struct() {
fn test_errors() { fn test_errors() {
invalid_array := fn () { invalid_array := fn () {
data := '{"countries":[{"cities":[{"name":"London"},{"name":"Manchester"}],"name":"UK"},{"cities":{"name":"Donlon"},"name":"KU"}],"users":{"Foo":{"age":10,"nums":[1,2,3],"lastName":"Johnson","IsRegistered":true,"type":0,"pet_animals":"little foo"},"Boo":{"age":20,"nums":[5,3,1],"lastName":"Smith","IsRegistered":false,"type":4,"pet_animals":"little boo"}},"extra":{"2":{"n1":2,"n2":4,"n3":8,"n4":16},"3":{"n1":3,"n2":9,"n3":27,"n4":81}}}' data := '{"countries":[{"cities":[{"name":"London"},{"name":"Manchester"}],"name":"UK"},{"cities":{"name":"Donlon"},"name":"KU"}],"users":{"Foo":{"age":10,"nums":[1,2,3],"lastName":"Johnson","IsRegistered":true,"type":0,"pet_animals":"little foo"},"Boo":{"age":20,"nums":[5,3,1],"lastName":"Smith","IsRegistered":false,"type":4,"pet_animals":"little boo"}},"extra":{"2":{"n1":2,"n2":4,"n3":8,"n4":16},"3":{"n1":3,"n2":9,"n3":27,"n4":81}}}'
json.decode<Data>(data) or { json.decode[Data](data) or {
assert err.msg().starts_with('Json element is not an array:') assert err.msg().starts_with('Json element is not an array:')
return return
} }
@ -310,7 +310,7 @@ fn test_errors() {
} }
invalid_object := fn () { invalid_object := fn () {
data := '{"countries":[{"cities":[{"name":"London"},{"name":"Manchester"}],"name":"UK"},{"cities":[{"name":"Donlon"},{"name":"Termanches"}],"name":"KU"}],"users":[{"age":10,"nums":[1,2,3],"lastName":"Johnson","IsRegistered":true,"type":0,"pet_animals":"little foo"},{"age":20,"nums":[5,3,1],"lastName":"Smith","IsRegistered":false,"type":4,"pet_animals":"little boo"}],"extra":{"2":{"n1":2,"n2":4,"n3":8,"n4":16},"3":{"n1":3,"n2":9,"n3":27,"n4":81}}}' data := '{"countries":[{"cities":[{"name":"London"},{"name":"Manchester"}],"name":"UK"},{"cities":[{"name":"Donlon"},{"name":"Termanches"}],"name":"KU"}],"users":[{"age":10,"nums":[1,2,3],"lastName":"Johnson","IsRegistered":true,"type":0,"pet_animals":"little foo"},{"age":20,"nums":[5,3,1],"lastName":"Smith","IsRegistered":false,"type":4,"pet_animals":"little boo"}],"extra":{"2":{"n1":2,"n2":4,"n3":8,"n4":16},"3":{"n1":3,"n2":9,"n3":27,"n4":81}}}'
json.decode<Data>(data) or { json.decode[Data](data) or {
assert err.msg().starts_with('Json element is not an object:') assert err.msg().starts_with('Json element is not an object:')
return return
} }
@ -330,7 +330,7 @@ struct Message {
//! BUGFIX - .from_json(res) //! BUGFIX - .from_json(res)
fn test_decode_alias_struct() { fn test_decode_alias_struct() {
msg := json.decode<Message>('{"id": "118499178790780929"}')! msg := json.decode[Message]('{"id": "118499178790780929"}')!
// hacky way of comparing aliased strings // hacky way of comparing aliased strings
assert msg.id.str() == '118499178790780929' assert msg.id.str() == '118499178790780929'
} }
@ -342,21 +342,21 @@ struct List {
//! BUGFIX - .from_json(res) //! BUGFIX - .from_json(res)
fn test_list() { fn test_list() {
list := json.decode<List>('{"id": 1, "items": ["1", "2"]}')! list := json.decode[List]('{"id": 1, "items": ["1", "2"]}')!
assert list.id == 1 assert list.id == 1
assert list.items == ['1', '2'] assert list.items == ['1', '2']
} }
//! BUGFIX - .from_json(res) //! BUGFIX - .from_json(res)
fn test_list_no_id() { fn test_list_no_id() {
list := json.decode<List>('{"items": ["1", "2"]}')! list := json.decode[List]('{"items": ["1", "2"]}')!
assert list.id == 0 assert list.id == 0
assert list.items == ['1', '2'] assert list.items == ['1', '2']
} }
//! BUGFIX - .from_json(res) //! BUGFIX - .from_json(res)
fn test_list_no_items() { fn test_list_no_items() {
list := json.decode<List>('{"id": 1}')! list := json.decode[List]('{"id": 1}')!
assert list.id == 1 assert list.id == 1
assert list.items == [] assert list.items == []
} }
@ -369,7 +369,7 @@ struct Info {
//! BUGFIX - .from_json(res) //! BUGFIX - .from_json(res)
fn test_decode_null_object() { fn test_decode_null_object() {
info := json.decode<Info>('{"id": 22, "items": null, "maps": null}')! info := json.decode[Info]('{"id": 22, "items": null, "maps": null}')!
assert info.id == 22 assert info.id == 22
assert '${info.items}' == '[]' assert '${info.items}' == '[]'
assert '${info.maps}' == '{}' assert '${info.maps}' == '{}'
@ -377,7 +377,7 @@ fn test_decode_null_object() {
//! BUGFIX - .from_json(res) //! BUGFIX - .from_json(res)
fn test_decode_missing_maps_field() { fn test_decode_missing_maps_field() {
info := json.decode<Info>('{"id": 22, "items": null}')! info := json.decode[Info]('{"id": 22, "items": null}')!
assert info.id == 22 assert info.id == 22
assert '${info.items}' == '[]' assert '${info.items}' == '[]'
assert '${info.maps}' == '{}' assert '${info.maps}' == '{}'