Skip to content

Commit f31aef9

Browse files
committed
feat: decode_to_json
1 parent c1e8ca6 commit f31aef9

4 files changed

Lines changed: 162 additions & 10 deletions

File tree

decode.v

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,107 @@ pub fn new_decoder() Decoder {
1919
return Decoder{}
2020
}
2121

22+
pub fn decode_to_json[T](src []u8) !string {
23+
mut d := new_decoder()
24+
25+
json := d.decode_to_json[T](src) or { return error('error decoding to JSON: ${err}') }
26+
27+
return json
28+
}
29+
30+
pub fn (mut d Decoder) decode_to_json[T](src []u8) !string {
31+
d.buffer = src
32+
d.next()!
33+
34+
mut result := ''
35+
36+
data := d.buffer
37+
38+
match d.bd {
39+
mp_array_16, mp_array_32, mp_fix_array_min...mp_fix_array_max {
40+
array_len := d.read_array_len(data) or { return error('error reading array length') }
41+
42+
mut d_for_array := new_decoder()
43+
44+
result += '['
45+
46+
for i in 0 .. array_len {
47+
if i > 0 {
48+
result += ','
49+
}
50+
51+
element_json := d_for_array.decode_to_json[T](data[1..]) or {
52+
return error('error converting array element to JSON ${err}')
53+
}
54+
55+
result += element_json
56+
}
57+
58+
result += ']'
59+
}
60+
mp_map_16, mp_map_32, mp_fix_map_min...mp_fix_map_max {
61+
map_len := d.read_map_len(src) or { return error('error reading map length') }
62+
63+
result += '{'
64+
65+
for i in 0 .. map_len {
66+
if i > 0 {
67+
result += ','
68+
}
69+
70+
key := d.decode_to_json[string](src) or {
71+
return error('error converting map key to JSON: ${err}')
72+
}
73+
74+
value_json := d.decode_to_json[T](src) or {
75+
return error('error converting map value to JSON')
76+
}
77+
78+
result += '${key}:${value_json}'
79+
}
80+
81+
result += '}'
82+
}
83+
mp_nil {
84+
result += 'null'
85+
}
86+
mp_true, mp_false {
87+
mut bool_val := false
88+
d.decode_bool(mut bool_val) or { return error('error decoding boolean: ${err}') }
89+
result += bool_val.str()
90+
}
91+
mp_f32, mp_f64 {
92+
mut float_val := 0.0
93+
d.decode_float(mut float_val) or { return error('error decoding float: ${err}') }
94+
result += float_val.str()
95+
}
96+
mp_u8, mp_u16, mp_u32, mp_u64, mp_i8, mp_i16, mp_i32, mp_i64 {
97+
mut int_val := 0
98+
d.decode_integer(mut int_val) or { return error('error decoding integer: ${err}') }
99+
result += int_val.str()
100+
}
101+
mp_str_8, mp_str_16, mp_str_32, mp_fix_str_min...mp_fix_str_max {
102+
mut str_val := ''
103+
d.decode_string(mut str_val) or { return error('error decoding string: ${err}') }
104+
result += '"${str_val}"'
105+
}
106+
mp_bin_8, mp_bin_16, mp_bin_32 {
107+
bin_len := d.read_bin_len(src) or { return error('error reading binary length') }
108+
for i in 0 .. bin_len {
109+
result += src[d.pos + i].str()
110+
}
111+
112+
d.pos += bin_len
113+
}
114+
mp_ext_8, mp_ext_16, mp_ext_32 {}
115+
mp_fix_ext_1, mp_fix_ext_2, mp_fix_ext_4, mp_fix_ext_8, mp_fix_ext_16 {}
116+
else {
117+
return error('unsupported descriptor byte for conversion to JSON')
118+
}
119+
}
120+
return result
121+
}
122+
22123
pub fn decode[T](src []u8) !T {
23124
mut val := T{}
24125

decode_to_json_test.v

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
module main
2+
3+
import msgpack
4+
import encoding.hex
5+
6+
fn test_decode_to_json_array_test() {
7+
src := msgpack.encode([1, 2])
8+
result := msgpack.decode_to_json[[]int](src) or { panic('error decoding to JSON ${err}') }
9+
assert result == '[1,2]'
10+
}
11+
12+
fn test_decode_to_json_map() {
13+
src := msgpack.encode({
14+
'key1': 1
15+
'key2': 2
16+
})
17+
result := msgpack.decode_to_json[map[string]int](src) or {
18+
panic('error decoding to JSON: ${err}')
19+
}
20+
assert result == '{"key1":1,"key2":2}'
21+
}
22+
23+
fn test_to_json_array() {
24+
src := msgpack.encode([1, 2])
25+
mut d := msgpack.new_decoder()
26+
result := d.decode_to_json[[]u64](src) or { panic('error converting to JSON: ${err}') }
27+
assert result == '[1,2]'
28+
}
29+
30+
fn test_to_json_map() {
31+
src := msgpack.encode({
32+
'key1': 1
33+
'key2': 2
34+
})
35+
mut d := msgpack.new_decoder()
36+
result := d.decode_to_json[map[string]int](src) or { panic('error converting to JSON') }
37+
assert result == '{"key1":1,"key2":2}'
38+
}

encode.v

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ pub fn encode[T](data T) []u8 {
1919
return encoder.encode(data)
2020
}
2121

22+
pub fn encode_to_json[T](data T) string {
23+
mut encoder := new_encoder()
24+
encoded := encoder.encode(data)
25+
return decode_to_json[T](encoded) or { '' }
26+
}
27+
2228
pub fn (e &Encoder) str() string {
2329
return e.buffer.hex()
2430
}

examples/bench_msgpack_json_vs_json2.v

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ fn main() {
3232
println('error: ${p}')
3333
}
3434
}
35-
b.measure('json.decode')
35+
b.measure('json.decode\n')
3636

3737
// encoding measurements:
3838
p := json.decode(Person, s)!
@@ -51,21 +51,28 @@ fn main() {
5151
println('json.encode error: ${es}')
5252
}
5353
}
54-
b.measure('json.encode')
54+
b.measure('json.encode\n')
5555

5656
for _ in 0 .. max_iterations {
57-
es := msgpack.encode[Person](p)
58-
if p.age != 99 {
57+
es := msgpack.encode_to_json[Person](p)
58+
if es[0] != `{` {
5959
println('error: ${es}')
6060
}
6161
}
62-
b.measure('msgpack.encode')
62+
b.measure('msgpack.encode_to_json')
6363

64-
encoded := msgpack.encode[Person](p)
65-
dump(encoded#[0..10])
6664
for _ in 0 .. max_iterations {
67-
// TODO: investigate why decoder.decode does not return a result at all :-|
68-
msgpack.decode[Person](encoded)!
65+
es := msgpack.encode[Person](p)
66+
if p.age != 99 {
67+
println('error: ${es}')
68+
}
6969
}
70-
b.measure('msgpack.decode')
70+
b.measure('msgpack.encode\n')
71+
72+
// Not working for now - waiting for #20027 be solved
73+
// encoded := msgpack.encode[Person](p)
74+
// for _ in 0 .. max_iterations {
75+
// msgpack.decode[Person](encoded)!
76+
// }
77+
// b.measure('msgpack.decode')
7178
}

0 commit comments

Comments
 (0)