v2 / vlib / v / tests / interface_generic_implements_test.v
105 lines · 88 sloc · 1.4 KB · 288ce180560f3a715e74c3fdf14fcfbbbe1c953a
Raw
1interface Foo[T] {
2 val T
3 foo() T
4}
5
6struct Bar[T] implements Foo[T] {
7 val T
8}
9
10fn (b Bar[T]) foo() T {
11 return b.val
12}
13
14fn test_main() {
15 b := Bar{
16 val: 0
17 }
18 assert b.foo() == 0
19}
20
21interface Any {}
22
23interface AInterface {
24 a int
25}
26
27struct StructA {
28mut:
29 a int
30}
31
32struct Container {
33mut:
34 any Any
35}
36
37fn (mut c Container) set[T](obj Any) {
38 c.any = obj
39}
40
41fn (c &Container) get[T]() !&T {
42 if c.any is T {
43 return c.any
44 }
45 return error('ops')
46}
47
48fn test_generic_interface_value_can_be_returned_as_interface_ref() {
49 a := &StructA{
50 a: 100
51 }
52 b := &StructA{
53 a: 200
54 }
55 mut c := &Container{
56 any: a
57 }
58 c.set[StructA](b)
59 c.set[AInterface](b)
60 d := c.get[StructA]() or { panic(err) }
61 e := c.get[AInterface]() or { panic(err) }
62 assert d.a == 200
63 assert e.a == 200
64}
65
66interface FilterModel {
67 model string
68}
69
70interface FilterCar {
71 name string
72}
73
74struct FilterCarRecord {
75 name string
76 model string
77}
78
79fn collect_matching[T](mut cars []FilterCar) []T {
80 mut matches := []T{}
81 for mut car in cars {
82 if mut car is T {
83 matches << car
84 }
85 }
86 return matches
87}
88
89fn test_generic_interface_to_interface_smartcast() {
90 mut cars := []FilterCar{}
91 cars << FilterCarRecord{
92 name: 'Roadster'
93 model: 'Tesla'
94 }
95 cars << FilterCarRecord{
96 name: 'Corolla'
97 model: 'Toyota'
98 }
99
100 models := collect_matching[FilterModel](mut cars)
101
102 assert models.len == 2
103 assert models[0].model == 'Tesla'
104 assert models[1].model == 'Toyota'
105}
106