-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunmarshal.c3
99 lines (68 loc) · 2.16 KB
/
unmarshal.c3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
module toml;
import std::io;
import std::collections::map;
import std::collections::object;
fault MarshalError
{
UNSUPPORTED_TYPE,
}
macro void! @unmarshal_obj(&t, m)
{
var $Type = $typeof(*t);
$foreach ($x : $Type.membersof)
// io::printn("-------");
// io::printfn("nameof: %s", $x.nameof);
// io::printfn("kindof: %s", $x.kindof);
// io::printfn("typeid: %s", $x.typeid.nameof);
// io::printfn("get value of membersof $x: %s", $x.get(*t));
if (m.has_key($x.nameof))
{
$switch ($x.kindof)
$case TypeKind.STRUCT:
@unmarshal_obj($x.get(*t), m.get($x.nameof)!)!;
$case TypeKind.VECTOR:
$case TypeKind.ARRAY:
Object* arr = m.get($x.nameof)!;
if (!arr.is_array())
{
io::eprintfn("TOML Unmarshal Error: should field '%s' really be an array?", $x.nameof);
return MarshalError.UNSUPPORTED_TYPE?;
}
var $ElementType = $typefrom($x.typeid.inner);
// io::printfn("array.len (Type): %d", $x.typeid.len);
// io::printfn("array.len (Object): %d", arr.get_len());
// io::printfn("type of array: %s", $x.typeid.nameof);
// io::printfn("type of array[0]: %s", $x.typeid.inner.nameof);
// io::printfn("type of array[0]: %s", $ElementType.nameof);
$if $ElementType.typeid == Object*.typeid:
usz n = min(arr.get_len(), $x.typeid.len);
if (n < arr.get_len())
{
io::eprintfn("TOML Unmarshal Warning: target array is smaller than config values!", $x.nameof);
}
for (usz i = 0; i < n; i++)
{
$x.get(*t)[i] = arr.get_at(i);
}
$else
io::eprintfn("TOML Unmarshal Error: type of field '%s' is unsupported; use 'Object*' instead.", $x.nameof);
return MarshalError.UNSUPPORTED_TYPE?;
$endif
$default:
var $TargetType = $typefrom($x.typeid);
$switch
$case types::is_int($TargetType):
$x.get(*t) = m.get_int($x.nameof)!;
$case types::is_float($TargetType):
$x.get(*t) = m.get_float($x.nameof)!;
$case types::is_bool($TargetType):
$x.get(*t) = m.get_bool($x.nameof)!;
$case $TargetType.typeid == String.typeid:
$x.get(*t) = m.get_string($x.nameof)!;
$default:
$x.get(*t) = m.get($x.nameof)!;
$endswitch
$endswitch
}
$endforeach
}