v2 / vlib / x / json2 / count.v
109 lines · 102 sloc · 2.12 KB · 3d60410b605d001e54f280070d5f952da9de1112
Raw
1module json2
2
3import time
4
5struct Count {
6mut:
7 total int
8}
9
10// get_total
11fn (mut count Count) get_total() int {
12 return count.total
13}
14
15// reset_total
16fn (mut count Count) reset_total() {
17 count.total = 0
18}
19
20// count_chars count json sizen without new encode
21fn (mut count Count) count_chars[T](val T) {
22 $if val is $option {
23 workaround := val
24 if workaround != none {
25 count.count_chars(val)
26 }
27 } $else $if T is string {
28 count.chars_in_string(val)
29 } $else $if T is $sumtype {
30 $for v in val.variants {
31 if val is v {
32 count.count_chars(val)
33 }
34 }
35 } $else $if T is $alias {
36 // TODO
37 } $else $if T is time.Time {
38 count.total += 26 // "YYYY-MM-DDTHH:mm:ss.123Z"
39 } $else $if T is $map {
40 count.total++ // {
41 for k, v in val {
42 count.count_chars(k)
43 count.total++ // :
44 count.count_chars(v)
45 }
46 count.total++ // }
47 } $else $if T is $array {
48 count.total += 2 // []
49 if val.len > 0 {
50 for element in val {
51 count.count_chars(element)
52 }
53 count.total += val.len - 1 // ,
54 }
55 } $else $if T is $struct {
56 count.chars_in_struct(val)
57 } $else $if T is $enum {
58 mut enum_name := 'unknown enum value'
59 $for member in T.values {
60 if member.value == val {
61 enum_name = member.name
62 for attr in member.attrs {
63 if json_attr := json_attr_value(attr) {
64 enum_name = json_attr
65 }
66 }
67 }
68 }
69 count.total += enum_name.len + 2 // ""
70 } $else $if T is $int {
71 // TODO: benchmark
72 mut abs_val := val
73 if val < 0 {
74 count.total++ // -
75 abs_val = -val
76 }
77 for number_value := abs_val; number_value >= 1; number_value /= 10 {
78 count.total++
79 }
80 if val == 0 {
81 count.total++
82 }
83 } $else $if T is $float {
84 // TODO
85 } $else $if T is bool {
86 if val {
87 count.total += 4 // true
88 } else {
89 count.total += 5 // false
90 }
91 } $else {
92 }
93}
94
95// chars_in_struct
96fn (mut count Count) chars_in_struct[T](val T) {
97 count.total += 2 // {}
98 $for field in T.fields {
99 // TODO: handle attributes
100 count.total += field.name.len + 3 // "":
101 workaround := val.$(field.name)
102 count.count_chars(workaround)
103 }
104}
105
106// chars_in_string
107fn (mut count Count) chars_in_string(val string) {
108 count.total += val.len + 2 // ""
109}
110