v2 / vlib / v / tests / generics / generics_fn_field_multi_instance_test.v
63 lines · 53 sloc · 1.03 KB · 2a6ed1aecf993df3f59cdbd455e27c7e8dcaea36
Raw
1type ProcedureHandler = fn () !string
2
3struct Procedure[T, U] {
4 value T
5 function fn (T) !U = unsafe { nil }
6}
7
8fn (p Procedure[T, U]) handle() !string {
9 result := p.function(p.value) or { return err }
10 return encode[U](result)
11}
12
13fn encode[T](value T) string {
14 $if T is Dog {
15 return 'dog:${value.name}'
16 }
17 $if T is Cat {
18 return 'cat:${value.name}'
19 }
20 return 'unknown'
21}
22
23struct Dog {
24 name string
25}
26
27struct NewDog {
28 name string
29}
30
31fn make_dog(value NewDog) !Dog {
32 return Dog{
33 name: value.name
34 }
35}
36
37struct Cat {
38 name string
39}
40
41struct NewCat {
42 name string
43}
44
45fn make_cat(value NewCat) !Cat {
46 return Cat{
47 name: value.name
48 }
49}
50
51fn test_generic_fn_field_multi_instance_specialization() {
52 dog := Procedure[NewDog, Dog]{
53 value: NewDog{'leo'}
54 function: make_dog
55 }
56 cat := Procedure[NewCat, Cat]{
57 value: NewCat{'milo'}
58 function: make_cat
59 }
60 handlers := [ProcedureHandler(dog.handle), ProcedureHandler(cat.handle)]
61 assert (handlers[0]() or { panic(err) }) == 'dog:leo'
62 assert (handlers[1]() or { panic(err) }) == 'cat:milo'
63}
64