1use crate::assert_err;
2
3use super::Dynamic;
4use anyhow::{Result, anyhow};
5
6macro_rules! vec_to_json {
7 ($buf:expr, $vec:expr, $variant:ident) => {{
8 $buf.push('[');
9 let mut once = ZOnce::new("", ",");
10 for value in $vec.iter() {
11 $buf.push_str(once.take());
12 Dynamic::$variant(value.clone()).to_json($buf);
13 }
14 $buf.push(']');
15 }};
16}
17
18pub(crate) fn skip_white(buf: &[u8]) -> Result<usize> {
19 let mut pos = 0usize;
20 while pos < buf.len() && (buf[pos] == b' ' || buf[pos] == b'\r' || buf[pos] == b'\t' || buf[pos] == b'\n') {
21 pos += 1;
22 }
23 if pos < buf.len() { Ok(pos) } else { Err(anyhow!("no more data")) }
24}
25
26const TOKEN: &[u8] = b"01234567890.-+truefalsenull"; pub trait FromJson: Sized {
28 fn from_json(buf: &[u8]) -> Result<(Self, usize)>;
29 fn get_token(buf: &[u8]) -> Result<(&str, usize)> {
30 let mut pos = 0usize;
31 while pos < buf.len() && TOKEN.contains(&buf[pos]) {
32 pos += 1;
33 }
34 Ok((std::str::from_utf8(&buf[..pos])?, pos))
35 }
36
37 fn get_string(buf: &[u8]) -> Result<(String, usize)> {
38 let mut pos = 1usize;
39 let mut vec = Vec::new();
40 while pos < buf.len() && buf[pos] != b'"' {
41 if buf[pos] == b'\\' {
42 pos += 1;
43 if pos == buf.len() {
44 return Err(anyhow!("uncomplete string"));
45 }
46 match buf[pos] {
47 b'\\' => vec.push(b'\\'),
48 b'"' => vec.push(b'\"'),
49 b'r' => vec.push(b'\r'),
50 b'n' => vec.push(b'\n'),
51 b't' => vec.push(b'\t'),
52 b'u' => {
53 let unicode_str = unsafe { std::str::from_utf8_unchecked(&buf[(pos + 1)..(pos + 5)]) };
54 if let Ok(unicode) = u32::from_str_radix(unicode_str, 16) {
55 if unicode < 0x80 {
56 vec.push(unicode as u8);
57 } else {
58 if let Some(unicode_char) = char::from_u32(unicode) {
59 unicode_char.encode_utf8(&mut vec);
60 }
61 }
62 }
63 pos += 4;
64 }
65 _ => {
66 return Err(anyhow!("unknow escape {}", buf[pos]));
67 }
68 }
69 } else {
70 vec.push(buf[pos]);
71 }
72 pos += 1;
73 }
74 if pos < buf.len() {
75 pos += 1;
76 }
77 Ok(String::from_utf8(vec).map(|s| (s, pos))?)
78 }
79}
80
81pub trait ToJson {
82 fn to_json(&self, buf: &mut String);
83}
84
85use indexmap::IndexMap;
86use parking_lot::RwLock;
87use smol_str::SmolStr;
88use std::sync::Arc;
89
90impl FromJson for Dynamic {
91 fn from_json(buf: &[u8]) -> Result<(Self, usize)> {
92 let mut pos = skip_white(buf)?;
93 if buf[pos] == b'[' {
94 pos += 1;
95 pos += skip_white(&buf[pos..])?;
96 let mut vec = Vec::<Self>::new();
97 while buf[pos] != b']' {
98 let (item, size) = Self::from_json(&buf[pos..])?;
99 vec.push(item);
100 pos += size;
101 pos += skip_white(&buf[pos..])?;
102 if buf[pos] == b',' {
103 pos += 1;
104 pos += skip_white(&buf[pos..])?;
105 }
106 }
107 Ok((Dynamic::List(Arc::new(RwLock::new(vec))), pos + 1))
108 } else if buf[pos] == b'{' {
109 pos += 1;
110 pos += skip_white(&buf[pos..])?;
111 let mut map = IndexMap::new();
112 while buf[pos] != b'}' {
113 assert_err!(buf[pos] != b'"', anyhow!("need a string key {:?}", String::from_utf8_lossy(&buf[pos..])));
114 let (key, size) = Self::get_string(&buf[pos..])?;
115 pos += size;
116 pos += skip_white(&buf[pos..])?;
117 assert_err!(buf[pos] != b':', anyhow!("need a :"));
118 pos += 1;
119 pos += skip_white(&buf[pos..])?;
120 let (item, size) = Self::from_json(&buf[pos..])?;
121 map.insert(SmolStr::from(key), item);
122 pos += size;
123 pos += skip_white(&buf[pos..])?;
124 if buf[pos] == b',' {
125 pos += 1;
126 pos += skip_white(&buf[pos..])?;
127 }
128 }
129 Ok((Dynamic::Map(Arc::new(RwLock::new(map))), pos + 1))
130 } else if buf[pos] == b'"' {
131 let (s, size) = Self::get_string(&buf[pos..])?;
132 Ok((SmolStr::from(s).into(), size))
133 } else {
134 let (token, size) = Self::get_token(&buf[pos..])?;
135 if token == "true" {
136 Ok((Dynamic::from(true), size))
137 } else if token == "false" {
138 Ok((Dynamic::from(false), size))
139 } else if token == "null" {
140 Ok((Dynamic::Null, size))
141 } else if token.contains('.') {
142 let v = token.parse::<f64>()?;
143 Ok((Dynamic::from(v), size))
144 } else {
145 let v = token.parse::<i64>()?;
146 Ok((Dynamic::from(v), size))
147 }
148 }
149 }
150}
151
152impl ToJson for &str {
153 fn to_json(&self, buf: &mut String) {
154 let mut formatted = self.as_bytes().iter().fold(vec![b'\"'], |mut vec, ch| match ch {
155 b'\"' => {
156 vec.extend_from_slice(&[0x5c, 0x22]);
157 vec
158 }
159 b'\\' => {
160 vec.extend_from_slice(&[0x5c, 0x5c]);
161 vec
162 }
163 b'\n' => {
164 vec.extend_from_slice(&[0x5c, 0x6e]);
165 vec
166 }
167 b'\r' => {
168 vec.extend_from_slice(&[0x5c, 0x72]);
169 vec
170 }
171 b'\t' => {
172 vec.extend_from_slice(&[0x5c, 0x74]);
173 vec
174 }
175 _ => {
176 vec.push(*ch);
177 vec
178 }
179 });
180 formatted.push(b'\"');
181 buf.push_str(unsafe { std::str::from_utf8_unchecked(&formatted) });
182 }
183}
184
185impl ToJson for i64 {
186 fn to_json(&self, buf: &mut String) {
187 buf.push_str(&self.to_string());
188 }
189}
190
191use super::ZOnce;
192
193impl ToJson for Dynamic {
194 fn to_json(&self, buf: &mut String) {
195 match self {
196 Self::Iter { idx: _, keys: _, value: _ } => {}
197 Self::Bool(b) => {
198 if *b {
199 buf.push_str("true")
200 } else {
201 buf.push_str("false")
202 }
203 }
204 Self::F16(bits) => buf.push_str(&super::f16_to_f64(*bits).to_string()),
205 Self::F32(f) => buf.push_str(&f.to_string()),
206 Self::F64(f) => buf.push_str(&f.to_string()),
207 Self::I8(i) => buf.push_str(&i.to_string()),
208 Self::I16(i) => buf.push_str(&i.to_string()),
209 Self::I32(i) => buf.push_str(&i.to_string()),
210 Self::I64(i) => buf.push_str(&i.to_string()),
211 Self::U8(i) => buf.push_str(&i.to_string()),
212 Self::U16(i) => buf.push_str(&i.to_string()),
213 Self::U32(i) => buf.push_str(&i.to_string()),
214 Self::U64(i) => buf.push_str(&i.to_string()),
215 Self::Null => buf.push_str("null"),
216 Self::String(s) => s.as_str().to_json(buf),
217 Self::StringBuf(s) => s.as_str().to_json(buf),
218 Self::Bytes(vec) => vec_to_json!(buf, vec, U8),
219 Self::VecI8(vec) => vec_to_json!(buf, vec, I8),
220 Self::VecU16(vec) => vec_to_json!(buf, vec, U16),
221 Self::VecI16(vec) => vec_to_json!(buf, vec, I16),
222 Self::VecU32(vec) => vec_to_json!(buf, vec, U32),
223 Self::VecI32(vec) => vec_to_json!(buf, vec, I32),
224 Self::VecF32(vec) => vec_to_json!(buf, vec, F32),
225 Self::VecU64(vec) => vec_to_json!(buf, vec, U64),
226 Self::VecI64(vec) => vec_to_json!(buf, vec, I64),
227 Self::VecF64(vec) => vec_to_json!(buf, vec, F64),
228 Self::List(a) => {
229 buf.push('[');
230 let mut once = ZOnce::new("", ",\n");
231 a.read().iter().for_each(|item| {
232 buf.push_str(once.take());
233 item.to_json(buf);
234 });
235 buf.push(']');
236 }
237 Self::Map(map) => {
238 buf.push('{');
239 let mut once = ZOnce::new("", ",\n");
240 map.read().iter().for_each(|(k, v)| {
241 buf.push_str(once.take());
242 k.as_str().to_json(buf);
243 buf.push_str(": ");
244 v.to_json(buf);
245 });
246 buf.push_str("}\n");
247 }
248 Self::StructView { .. } | Self::StructOwned { .. } => {
249 buf.push('{');
250 let mut once = ZOnce::new("", ",\n");
251 self.keys().iter().for_each(|k| {
252 buf.push_str(once.take());
253 k.as_str().to_json(buf);
254 buf.push_str(": ");
255 self.get_dynamic(k).unwrap_or(Dynamic::Null).to_json(buf);
256 });
257 buf.push_str("}\n");
258 }
259 Self::Custom(value) => {
260 buf.push_str("{\"@custom\":");
261 value.custom_type_name().to_json(buf);
262 buf.push('}');
263 }
264 }
265 }
266}