nodedb_types/json_msgpack/
writer.rs1use super::json_value::JsonValue;
6
7#[inline]
9pub fn json_to_msgpack(value: &serde_json::Value) -> zerompk::Result<Vec<u8>> {
10 zerompk::to_msgpack_vec(&JsonValue(value.clone()))
11}
12
13#[inline]
20pub fn json_to_msgpack_or_empty(value: &serde_json::Value) -> Vec<u8> {
21 json_to_msgpack(value).unwrap_or_else(|_| vec![0x80])
22}
23
24pub fn value_to_msgpack(value: &crate::Value) -> zerompk::Result<Vec<u8>> {
29 let mut buf = Vec::with_capacity(128);
30 write_native_value(&mut buf, value);
31 Ok(buf)
32}
33
34fn write_native_value(buf: &mut Vec<u8>, value: &crate::Value) {
36 match value {
37 crate::Value::Null => buf.push(0xC0),
38 crate::Value::Bool(false) => buf.push(0xC2),
39 crate::Value::Bool(true) => buf.push(0xC3),
40 crate::Value::Integer(i) => write_native_int(buf, *i),
41 crate::Value::Float(f) => {
42 buf.push(0xCB);
43 buf.extend_from_slice(&f.to_be_bytes());
44 }
45 crate::Value::String(s)
46 | crate::Value::Uuid(s)
47 | crate::Value::Ulid(s)
48 | crate::Value::Regex(s) => write_native_str(buf, s),
49 crate::Value::Bytes(b) => write_native_bin(buf, b),
50 crate::Value::Array(arr) | crate::Value::Set(arr) => {
51 write_native_array_header(buf, arr.len());
52 for v in arr {
53 write_native_value(buf, v);
54 }
55 }
56 crate::Value::Object(map) => {
57 write_native_map_header(buf, map.len());
58 for (k, v) in map {
59 write_native_str(buf, k);
60 write_native_value(buf, v);
61 }
62 }
63 crate::Value::DateTime(dt) | crate::Value::NaiveDateTime(dt) => {
64 write_native_str(buf, &dt.to_string())
65 }
66 crate::Value::Duration(d) => write_native_str(buf, &d.to_string()),
67 crate::Value::Decimal(d) => write_native_str(buf, &d.to_string()),
68 crate::Value::Geometry(g) => {
69 if let Ok(s) = sonic_rs::to_string(g) {
70 write_native_str(buf, &s);
71 } else {
72 buf.push(0xC0);
73 }
74 }
75 crate::Value::Range { .. } | crate::Value::Record { .. } => buf.push(0xC0),
76 crate::Value::Vector(v) => {
77 write_native_array_header(buf, v.len());
80 for f in v.iter() {
81 buf.push(0xCB);
82 buf.extend_from_slice(&(*f as f64).to_be_bytes());
83 }
84 }
85 crate::Value::ArrayCell(cell) => {
91 let map_len = if cell.system_time.is_some() { 3 } else { 2 };
92 write_native_map_header(buf, map_len);
93 write_native_str(buf, "coords");
94 write_native_array_header(buf, cell.coords.len());
95 for v in &cell.coords {
96 write_native_value(buf, v);
97 }
98 write_native_str(buf, "attrs");
99 write_native_array_header(buf, cell.attrs.len());
100 for v in &cell.attrs {
101 write_native_value(buf, v);
102 }
103 if let Some(ts) = cell.system_time {
104 write_native_str(buf, "_ts_system");
105 write_native_int(buf, ts);
106 }
107 }
108 }
109}
110
111fn write_native_int(buf: &mut Vec<u8>, i: i64) {
112 if (0..=0x7F).contains(&i) {
113 buf.push(i as u8);
114 } else if (-32..0).contains(&i) {
115 buf.push(i as u8); } else if i >= i8::MIN as i64 && i <= i8::MAX as i64 {
117 buf.push(0xD0);
118 buf.push(i as i8 as u8);
119 } else if i >= i16::MIN as i64 && i <= i16::MAX as i64 {
120 buf.push(0xD1);
121 buf.extend_from_slice(&(i as i16).to_be_bytes());
122 } else if i >= i32::MIN as i64 && i <= i32::MAX as i64 {
123 buf.push(0xD2);
124 buf.extend_from_slice(&(i as i32).to_be_bytes());
125 } else {
126 buf.push(0xD3);
127 buf.extend_from_slice(&i.to_be_bytes());
128 }
129}
130
131fn write_native_str(buf: &mut Vec<u8>, s: &str) {
132 let len = s.len();
133 if len < 32 {
134 buf.push(0xA0 | len as u8);
135 } else if len <= u8::MAX as usize {
136 buf.push(0xD9);
137 buf.push(len as u8);
138 } else if len <= u16::MAX as usize {
139 buf.push(0xDA);
140 buf.extend_from_slice(&(len as u16).to_be_bytes());
141 } else {
142 buf.push(0xDB);
143 buf.extend_from_slice(&(len as u32).to_be_bytes());
144 }
145 buf.extend_from_slice(s.as_bytes());
146}
147
148fn write_native_bin(buf: &mut Vec<u8>, b: &[u8]) {
149 let len = b.len();
150 if len <= u8::MAX as usize {
151 buf.push(0xC4);
152 buf.push(len as u8);
153 } else if len <= u16::MAX as usize {
154 buf.push(0xC5);
155 buf.extend_from_slice(&(len as u16).to_be_bytes());
156 } else {
157 buf.push(0xC6);
158 buf.extend_from_slice(&(len as u32).to_be_bytes());
159 }
160 buf.extend_from_slice(b);
161}
162
163fn write_native_array_header(buf: &mut Vec<u8>, len: usize) {
164 if len < 16 {
165 buf.push(0x90 | len as u8);
166 } else if len <= u16::MAX as usize {
167 buf.push(0xDC);
168 buf.extend_from_slice(&(len as u16).to_be_bytes());
169 } else {
170 buf.push(0xDD);
171 buf.extend_from_slice(&(len as u32).to_be_bytes());
172 }
173}
174
175fn write_native_map_header(buf: &mut Vec<u8>, len: usize) {
176 if len < 16 {
177 buf.push(0x80 | len as u8);
178 } else if len <= u16::MAX as usize {
179 buf.push(0xDE);
180 buf.extend_from_slice(&(len as u16).to_be_bytes());
181 } else {
182 buf.push(0xDF);
183 buf.extend_from_slice(&(len as u32).to_be_bytes());
184 }
185}