nodedb_types/json_msgpack/
writer.rs1use super::json_value::JsonValue;
4
5#[inline]
7pub fn json_to_msgpack(value: &serde_json::Value) -> zerompk::Result<Vec<u8>> {
8 zerompk::to_msgpack_vec(&JsonValue(value.clone()))
9}
10
11#[inline]
18pub fn json_to_msgpack_or_empty(value: &serde_json::Value) -> Vec<u8> {
19 json_to_msgpack(value).unwrap_or_else(|_| vec![0x80])
20}
21
22pub fn value_to_msgpack(value: &crate::Value) -> zerompk::Result<Vec<u8>> {
27 let mut buf = Vec::with_capacity(128);
28 write_native_value(&mut buf, value);
29 Ok(buf)
30}
31
32fn write_native_value(buf: &mut Vec<u8>, value: &crate::Value) {
34 match value {
35 crate::Value::Null => buf.push(0xC0),
36 crate::Value::Bool(false) => buf.push(0xC2),
37 crate::Value::Bool(true) => buf.push(0xC3),
38 crate::Value::Integer(i) => write_native_int(buf, *i),
39 crate::Value::Float(f) => {
40 buf.push(0xCB);
41 buf.extend_from_slice(&f.to_be_bytes());
42 }
43 crate::Value::String(s)
44 | crate::Value::Uuid(s)
45 | crate::Value::Ulid(s)
46 | crate::Value::Regex(s) => write_native_str(buf, s),
47 crate::Value::Bytes(b) => write_native_bin(buf, b),
48 crate::Value::Array(arr) | crate::Value::Set(arr) => {
49 write_native_array_header(buf, arr.len());
50 for v in arr {
51 write_native_value(buf, v);
52 }
53 }
54 crate::Value::Object(map) => {
55 write_native_map_header(buf, map.len());
56 for (k, v) in map {
57 write_native_str(buf, k);
58 write_native_value(buf, v);
59 }
60 }
61 crate::Value::DateTime(dt) => write_native_str(buf, &dt.to_string()),
62 crate::Value::Duration(d) => write_native_str(buf, &d.to_string()),
63 crate::Value::Decimal(d) => write_native_str(buf, &d.to_string()),
64 crate::Value::Geometry(g) => {
65 if let Ok(s) = serde_json::to_string(g) {
66 write_native_str(buf, &s);
67 } else {
68 buf.push(0xC0);
69 }
70 }
71 crate::Value::Range { .. } | crate::Value::Record { .. } => buf.push(0xC0),
72 }
73}
74
75fn write_native_int(buf: &mut Vec<u8>, i: i64) {
76 if (0..=0x7F).contains(&i) {
77 buf.push(i as u8);
78 } else if (-32..0).contains(&i) {
79 buf.push(i as u8); } else if i >= i8::MIN as i64 && i <= i8::MAX as i64 {
81 buf.push(0xD0);
82 buf.push(i as i8 as u8);
83 } else if i >= i16::MIN as i64 && i <= i16::MAX as i64 {
84 buf.push(0xD1);
85 buf.extend_from_slice(&(i as i16).to_be_bytes());
86 } else if i >= i32::MIN as i64 && i <= i32::MAX as i64 {
87 buf.push(0xD2);
88 buf.extend_from_slice(&(i as i32).to_be_bytes());
89 } else {
90 buf.push(0xD3);
91 buf.extend_from_slice(&i.to_be_bytes());
92 }
93}
94
95fn write_native_str(buf: &mut Vec<u8>, s: &str) {
96 let len = s.len();
97 if len < 32 {
98 buf.push(0xA0 | len as u8);
99 } else if len <= u8::MAX as usize {
100 buf.push(0xD9);
101 buf.push(len as u8);
102 } else if len <= u16::MAX as usize {
103 buf.push(0xDA);
104 buf.extend_from_slice(&(len as u16).to_be_bytes());
105 } else {
106 buf.push(0xDB);
107 buf.extend_from_slice(&(len as u32).to_be_bytes());
108 }
109 buf.extend_from_slice(s.as_bytes());
110}
111
112fn write_native_bin(buf: &mut Vec<u8>, b: &[u8]) {
113 let len = b.len();
114 if len <= u8::MAX as usize {
115 buf.push(0xC4);
116 buf.push(len as u8);
117 } else if len <= u16::MAX as usize {
118 buf.push(0xC5);
119 buf.extend_from_slice(&(len as u16).to_be_bytes());
120 } else {
121 buf.push(0xC6);
122 buf.extend_from_slice(&(len as u32).to_be_bytes());
123 }
124 buf.extend_from_slice(b);
125}
126
127fn write_native_array_header(buf: &mut Vec<u8>, len: usize) {
128 if len < 16 {
129 buf.push(0x90 | len as u8);
130 } else if len <= u16::MAX as usize {
131 buf.push(0xDC);
132 buf.extend_from_slice(&(len as u16).to_be_bytes());
133 } else {
134 buf.push(0xDD);
135 buf.extend_from_slice(&(len as u32).to_be_bytes());
136 }
137}
138
139fn write_native_map_header(buf: &mut Vec<u8>, len: usize) {
140 if len < 16 {
141 buf.push(0x80 | len as u8);
142 } else if len <= u16::MAX as usize {
143 buf.push(0xDE);
144 buf.extend_from_slice(&(len as u16).to_be_bytes());
145 } else {
146 buf.push(0xDF);
147 buf.extend_from_slice(&(len as u32).to_be_bytes());
148 }
149}