@@ -25,33 +25,31 @@ pub enum ValueKind {
25
25
boolean
26
26
}
27
27
28
- // check_json
28
+ // check_json checks if the JSON string is valid.
29
29
fn check_json (val string ) ! {
30
30
if val == '' {
31
31
return error ('empty string' )
32
32
}
33
33
}
34
34
35
- // decode
35
+ // decode decodes a JSON string into a specified type.
36
36
pub fn decode [T](val string ) ! T {
37
37
check_json (val)!
38
38
39
39
mut nodes := []Node{}
40
-
41
40
mut decoder := Decoder{
42
41
json: val
43
42
}
44
43
45
- // TODO needs performance improvements
44
+ // TODO: needs performance improvements
46
45
decoder.fulfill_nodes (mut nodes)
47
46
48
47
mut result := T{}
49
-
50
48
decoder.decode_value (nodes, & result)
51
49
return result
52
50
}
53
51
54
- // decode_value
52
+ // decode_value decodes a value from the JSON nodes.
55
53
fn (mut decoder Decoder) decode_value [T](nodes []Node, val & T) {
56
54
$if val is $option {
57
55
} $else $if T is string {
@@ -76,32 +74,23 @@ fn (mut decoder Decoder) decode_value[T](nodes []Node, val &T) {
76
74
}
77
75
}
78
76
77
+ // get_value_kind returns the kind of a JSON value.
79
78
fn get_value_kind (value rune ) ValueKind {
80
- mut value_kind := ValueKind.unknown
81
-
82
- if value == `"` {
83
- value_kind = .string_
84
- } else if value == `t` || value == `f` {
85
- value_kind = .boolean
86
- } else if value == `{` {
87
- value_kind = .object
88
- } else if value == `[` {
89
- value_kind = .array
90
- } else if value > = `0` && value < = `9` {
91
- value_kind = .number
79
+ return match value {
80
+ `"` { .string_ }
81
+ `t` , `f` { .boolean }
82
+ `{` { .object }
83
+ `[` { .array }
84
+ `0` ...`9` { .number }
85
+ else { .unknown }
92
86
}
93
- return value_kind
94
87
}
95
88
96
- // decode_optional_value_in_actual_node
89
+ // decode_optional_value_in_actual_node decodes an optional value in a node.
97
90
fn (mut decoder Decoder) decode_optional_value_in_actual_node [T](node Node, val ? T) T {
98
91
start := (node.key_pos + node.key_len) + 3
99
92
mut end := start
100
- for {
101
- if decoder.json[end] == `,` || decoder.json[end] == `}` {
102
- break
103
- }
104
-
93
+ for decoder.json[end] != `,` && decoder.json[end] != `}` {
105
94
end++
106
95
}
107
96
mut value_kind := get_value_kind (decoder.json[start])
@@ -127,7 +116,7 @@ fn (mut decoder Decoder) decode_optional_value_in_actual_node[T](node Node, val
127
116
return T{}
128
117
}
129
118
130
- // decode_struct
119
+ // decode_struct decodes a struct from the JSON nodes.
131
120
fn (mut decoder Decoder) decode_struct [T](nodes []Node, value & T) {
132
121
$for field in T.fields {
133
122
for i := 0 ; i < nodes.len; i++ {
@@ -140,15 +129,10 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
140
129
} {
141
130
start := (node.key_pos + node.key_len) + 3
142
131
mut end := start
143
- for {
144
- if decoder.json[end] == `,` || decoder.json[end] == `}` {
145
- break
146
- }
147
-
132
+ for decoder.json[end] != `,` && decoder.json[end] != `}` {
148
133
end++
149
134
}
150
-
151
- mut value_kind := get_value_kind (decoder.json[start])
135
+ value_kind := get_value_kind (decoder.json[start])
152
136
$if field.indirections != 0 {
153
137
// REVIEW Needs clone?
154
138
$if field.indirections == 1 {
@@ -257,10 +241,10 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
257
241
} else {
258
242
}
259
243
} $else $if field.typ is string {
260
- if value_kind == .string_ {
261
- value.$(field.name) = decoder.json[start + 1 ..end - 1 ]
244
+ value.$(field.name) = if value_kind == .string_ {
245
+ decoder.json[start + 1 ..end - 1 ]
262
246
} else {
263
- value.$(field.name) = decoder.json[start..end]
247
+ decoder.json[start..end]
264
248
}
265
249
} $else $if field.typ in [$int , $float] {
266
250
$if field.typ is i8 {
@@ -287,11 +271,7 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
287
271
value.$(field.name) = decoder.json[start..end].f64 ()
288
272
}
289
273
} $else $if field.typ is bool {
290
- if decoder.json[start] == `t` {
291
- value.$(field.name) = true
292
- } else if decoder.json[start] == `f` {
293
- value.$(field.name) = false
294
- }
274
+ value.$(field.name) = decoder.json[start] == `t`
295
275
} $else $if field.typ is time.Time {
296
276
if value_kind == .string_ {
297
277
value.$(field.name) = time.parse_rfc3339 (decoder.json[start + 1 ..end - 1 ]) or {
@@ -300,20 +280,17 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
300
280
}
301
281
} $else $if field.typ is $struct {
302
282
if node.children != none {
303
- decoder.decode_value (node.children or { panic ('It will never happens ' ) },
283
+ decoder.decode_value (node.children or { panic ('It will never happen ' ) },
304
284
value.$(field.name))
305
285
}
306
286
} $else $if field.typ is $array {
307
287
if value_kind == .array {
308
288
// TODO
309
289
}
310
290
} $else $if field.typ is $map {
311
- if value_kind == .object {
312
- if node.children != none {
313
- decoder.decode_map (node.children or {
314
- panic ('It will never happens' )
315
- }, mut value.$(field.name))
316
- }
291
+ if value_kind == .object && node.children != none {
292
+ decoder.decode_map (node.children or { panic ('It will never happen' ) }, mut
293
+ value.$(field.name))
317
294
}
318
295
} $else $if field.typ is $enum {
319
296
value.$(field.name) = decoder.json[start..end].int ()
@@ -365,79 +342,75 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
365
342
}
366
343
}
367
344
}
368
- // }
369
345
}
370
346
}
371
347
372
- // fn (mut decoder Decoder) decode_map[K, V](nodes []Node, mut val map[K]V) {
348
+ // decode_map decodes a map from the JSON nodes.
373
349
fn (mut decoder Decoder) decode_map [T](nodes []Node, mut val T) {
374
350
for i := 0 ; i < nodes.len; i++ {
375
351
mut node := nodes[i]
376
352
377
353
start := (node.key_pos + node.key_len) + 3
378
354
mut end := start
379
-
380
- for {
381
- if decoder.json[end] == `,` || decoder.json[end] == `}` {
382
- break
383
- }
384
-
355
+ for decoder.json[end] != `,` && decoder.json[end] != `}` {
385
356
end++
386
357
}
387
-
388
- mut value_kind := get_value_kind (decoder.json[start])
389
-
390
- if value_kind == .string_ {
391
- val[decoder.json[node.key_pos..node.key_pos + node.key_len]] = decoder.json[start + 1 ..end - 1 ]
358
+ value_kind := get_value_kind (decoder.json[start])
359
+ val[decoder.json[node.key_pos..node.key_pos + node.key_len]] = if value_kind == .string_ {
360
+ decoder.json[start + 1 ..end - 1 ]
392
361
} else {
393
- val[decoder.json[node.key_pos..node.key_pos + node.key_len]] = decoder.json[start..end]
362
+ decoder.json[start..end]
394
363
}
395
364
}
396
365
}
397
366
398
- // fulfill_nodes
367
+ // fulfill_nodes fills the nodes from the JSON string.
399
368
fn (mut decoder Decoder) fulfill_nodes (mut nodes []Node) {
400
369
mut inside_string := false
401
370
mut inside_key := false
402
-
403
371
mut actual_key_len := 0
372
+
404
373
for decoder.idx < decoder.json.len {
405
374
letter := decoder.json[decoder.idx]
406
- if letter == ` ` && ! inside_string {
407
- } else if letter == `\" ` {
408
- if decoder.json[decoder.idx - 1 ] == `{` || decoder.json[decoder.idx - 2 ] == `,` {
409
- inside_key = true
410
- } else if decoder.json[decoder.idx + 1 ] == `:` {
411
- if decoder.json[decoder.idx + 3 ] == `{` {
412
- mut children := []Node{}
413
- key_pos := decoder.idx - actual_key_len
414
- key_len := actual_key_len
415
-
416
- decoder.idx + = 3
417
- decoder.fulfill_nodes (mut children)
418
-
419
- nodes << Node{
420
- key_pos: key_pos
421
- key_len: key_len
422
- children: children
423
- }
424
- } else {
425
- nodes << Node{
426
- key_pos: decoder.idx - actual_key_len
427
- key_len: actual_key_len
375
+ match letter {
376
+ ` ` {
377
+ if ! inside_string {
378
+ }
379
+ }
380
+ `\" ` {
381
+ if decoder.json[decoder.idx - 1 ] == `{` || decoder.json[decoder.idx - 2 ] == `,` {
382
+ inside_key = true
383
+ } else if decoder.json[decoder.idx + 1 ] == `:` {
384
+ if decoder.json[decoder.idx + 3 ] == `{` {
385
+ mut children := []Node{}
386
+ key_pos := decoder.idx - actual_key_len
387
+ key_len := actual_key_len
388
+
389
+ decoder.idx + = 3
390
+ decoder.fulfill_nodes (mut children)
391
+
392
+ nodes << Node{
393
+ key_pos: key_pos
394
+ key_len: key_len
395
+ children: children
396
+ }
397
+ } else {
398
+ nodes << Node{
399
+ key_pos: decoder.idx - actual_key_len
400
+ key_len: actual_key_len
401
+ }
428
402
}
403
+ inside_key = false
429
404
}
430
-
431
- inside_key = false
405
+ inside_string = ! inside_string
406
+ decoder.idx++
407
+ continue
432
408
}
433
- inside_string = ! inside_string
434
- decoder.idx++
435
- continue
436
- } else if letter == `:` {
437
- actual_key_len = 0
438
- } else if letter == `,` || letter == `:` || letter == `{` || letter == `}` || letter == `[`
439
- || letter == `]` {
440
- } else {
409
+ `:` {
410
+ actual_key_len = 0
411
+ }
412
+ `,` , `{` , `}` , `[` , `]` {}
413
+ else {}
441
414
}
442
415
if inside_key {
443
416
actual_key_len++
0 commit comments