@@ -25,33 +25,31 @@ pub enum ValueKind {
2525 boolean
2626}
2727
28- // check_json
28+ // check_json checks if the JSON string is valid.
2929fn check_json (val string ) ! {
3030 if val == '' {
3131 return error ('empty string' )
3232 }
3333}
3434
35- // decode
35+ // decode decodes a JSON string into a specified type.
3636pub fn decode [T](val string ) ! T {
3737 check_json (val)!
3838
3939 mut nodes := []Node{}
40-
4140 mut decoder := Decoder{
4241 json: val
4342 }
4443
45- // TODO needs performance improvements
44+ // TODO: needs performance improvements
4645 decoder.fulfill_nodes (mut nodes)
4746
4847 mut result := T{}
49-
5048 decoder.decode_value (nodes, & result)
5149 return result
5250}
5351
54- // decode_value
52+ // decode_value decodes a value from the JSON nodes.
5553fn (mut decoder Decoder) decode_value [T](nodes []Node, val & T) {
5654 $if val is $option {
5755 } $else $if T is string {
@@ -76,32 +74,23 @@ fn (mut decoder Decoder) decode_value[T](nodes []Node, val &T) {
7674 }
7775}
7876
77+ // get_value_kind returns the kind of a JSON value.
7978fn 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 }
9286 }
93- return value_kind
9487}
9588
96- // decode_optional_value_in_actual_node
89+ // decode_optional_value_in_actual_node decodes an optional value in a node.
9790fn (mut decoder Decoder) decode_optional_value_in_actual_node [T](node Node, val ? T) T {
9891 start := (node.key_pos + node.key_len) + 3
9992 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] != `}` {
10594 end++
10695 }
10796 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
127116 return T{}
128117}
129118
130- // decode_struct
119+ // decode_struct decodes a struct from the JSON nodes.
131120fn (mut decoder Decoder) decode_struct [T](nodes []Node, value & T) {
132121 $for field in T.fields {
133122 for i := 0 ; i < nodes.len; i++ {
@@ -140,15 +129,10 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
140129 } {
141130 start := (node.key_pos + node.key_len) + 3
142131 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] != `}` {
148133 end++
149134 }
150-
151- mut value_kind := get_value_kind (decoder.json[start])
135+ value_kind := get_value_kind (decoder.json[start])
152136 $if field.indirections != 0 {
153137 // REVIEW Needs clone?
154138 $if field.indirections == 1 {
@@ -257,10 +241,10 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
257241 } else {
258242 }
259243 } $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 ]
262246 } else {
263- value.$(field.name) = decoder.json[start..end]
247+ decoder.json[start..end]
264248 }
265249 } $else $if field.typ in [$int , $float] {
266250 $if field.typ is i8 {
@@ -287,11 +271,7 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
287271 value.$(field.name) = decoder.json[start..end].f64 ()
288272 }
289273 } $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`
295275 } $else $if field.typ is time.Time {
296276 if value_kind == .string_ {
297277 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) {
300280 }
301281 } $else $if field.typ is $struct {
302282 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 ' ) },
304284 value.$(field.name))
305285 }
306286 } $else $if field.typ is $array {
307287 if value_kind == .array {
308288 // TODO
309289 }
310290 } $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))
317294 }
318295 } $else $if field.typ is $enum {
319296 value.$(field.name) = decoder.json[start..end].int ()
@@ -365,79 +342,75 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
365342 }
366343 }
367344 }
368- // }
369345 }
370346}
371347
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.
373349fn (mut decoder Decoder) decode_map [T](nodes []Node, mut val T) {
374350 for i := 0 ; i < nodes.len; i++ {
375351 mut node := nodes[i]
376352
377353 start := (node.key_pos + node.key_len) + 3
378354 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] != `}` {
385356 end++
386357 }
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 ]
392361 } else {
393- val[decoder.json[node.key_pos..node.key_pos + node.key_len]] = decoder.json[start..end]
362+ decoder.json[start..end]
394363 }
395364 }
396365}
397366
398- // fulfill_nodes
367+ // fulfill_nodes fills the nodes from the JSON string.
399368fn (mut decoder Decoder) fulfill_nodes (mut nodes []Node) {
400369 mut inside_string := false
401370 mut inside_key := false
402-
403371 mut actual_key_len := 0
372+
404373 for decoder.idx < decoder.json.len {
405374 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+ }
428402 }
403+ inside_key = false
429404 }
430-
431- inside_key = false
405+ inside_string = ! inside_string
406+ decoder.idx++
407+ continue
432408 }
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 {}
441414 }
442415 if inside_key {
443416 actual_key_len++
0 commit comments