v2 / vlib / v / tests / comptime / comptime_unaliased_typ_test.v
63 lines · 56 sloc · 1.3 KB · 726a6821417698218b17d3e37ced80eb551a0581
Raw
1type StringAlias = string
2type BoolAlias = bool
3type IntAlias = int
4
5struct Decoder {
6 json string
7}
8
9pub fn decode[T](val string) !T {
10 mut decoder := Decoder{
11 json: val
12 }
13
14 mut result := T{}
15 decoder.decode_value(mut result)!
16 return result
17}
18
19fn (mut decoder Decoder) decode_value[T](mut val T) ! {
20 $if T.unaliased_typ is string {
21 } $else $if T.unaliased_typ in [$int, $float, $enum] {
22 bytes := unsafe { decoder.json.str.vbytes(decoder.json.len) }
23 unsafe {
24 string_buffer_to_generic_number(mut val, bytes)
25 }
26 } $else {
27 return error('cannot encode value with ${typeof(val).name} type')
28 }
29}
30
31@[direct_array_access; unsafe]
32pub fn string_buffer_to_generic_number[T](mut result T, data []u8) {
33 $if T is $option {
34 } $else $if T.unaliased_typ is string {
35 panic('should not happens')
36 } $else $if T.unaliased_typ is $int {
37 mut is_negative := false
38 for ch in data {
39 if ch == `-` {
40 is_negative = true
41 continue
42 }
43 digit := T(ch - `0`)
44 result = T(*result * 10 + digit)
45 }
46 if is_negative {
47 result *= -1
48 }
49 } $else {
50 panic('unsupported type ${typeof[T]().name}')
51 }
52}
53
54fn test_main() {
55 value := '1234567890123456789'
56 _ := decode[int](value)!
57 _ := decode[IntAlias](value)!
58 _ := decode[StringAlias]('"abcd"')!
59 _ := decode[int](value)!
60 _ := decode[string]('"abcd"')!
61
62 assert true
63}
64