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 smol_str::SmolStr;
86use std::{
87 collections::BTreeMap,
88 sync::{Arc, RwLock},
89};
90
91impl FromJson for Dynamic {
92 fn from_json(buf: &[u8]) -> Result<(Self, usize)> {
93 let mut pos = skip_white(buf)?;
94 if buf[pos] == b'[' {
95 pos += 1;
96 pos += skip_white(&buf[pos..])?;
97 let mut vec = Vec::<Self>::new();
98 while buf[pos] != b']' {
99 let (item, size) = Self::from_json(&buf[pos..])?;
100 vec.push(item);
101 pos += size;
102 pos += skip_white(&buf[pos..])?;
103 if buf[pos] == b',' {
104 pos += 1;
105 pos += skip_white(&buf[pos..])?;
106 }
107 }
108 Ok((Dynamic::List(Arc::new(RwLock::new(vec))), pos + 1))
109 } else if buf[pos] == b'{' {
110 pos += 1;
111 pos += skip_white(&buf[pos..])?;
112 let mut map = BTreeMap::new();
113 while buf[pos] != b'}' {
114 assert_err!(buf[pos] != b'"', anyhow!("need a string key {:?}", String::from_utf8_lossy(&buf[pos..])));
115 let (key, size) = Self::get_string(&buf[pos..])?;
116 pos += size;
117 pos += skip_white(&buf[pos..])?;
118 assert_err!(buf[pos] != b':', anyhow!("need a :"));
119 pos += 1;
120 pos += skip_white(&buf[pos..])?;
121 let (item, size) = Self::from_json(&buf[pos..])?;
122 map.insert(SmolStr::from(key), item);
123 pos += size;
124 pos += skip_white(&buf[pos..])?;
125 if buf[pos] == b',' {
126 pos += 1;
127 pos += skip_white(&buf[pos..])?;
128 }
129 }
130 Ok((Dynamic::Map(Arc::new(RwLock::new(map))), pos + 1))
131 } else if buf[pos] == b'"' {
132 let (s, size) = Self::get_string(&buf[pos..])?;
133 Ok((SmolStr::from(s).into(), size))
134 } else {
135 let (token, size) = Self::get_token(&buf[pos..])?;
136 if token == "true" {
137 Ok((Dynamic::from(true), size))
138 } else if token == "false" {
139 Ok((Dynamic::from(false), size))
140 } else if token == "null" {
141 Ok((Dynamic::Null, size))
142 } else if token.contains('.') {
143 let v = token.parse::<f64>()?;
144 Ok((Dynamic::from(v), size))
145 } else {
146 let v = token.parse::<i64>()?;
147 Ok((Dynamic::from(v), size))
148 }
149 }
150 }
151}
152
153impl ToJson for &str {
154 fn to_json(&self, buf: &mut String) {
155 let mut formatted = self.as_bytes().iter().fold(vec![b'\"'], |mut vec, ch| match ch {
156 b'\"' => {
157 vec.extend_from_slice(&[0x5c, 0x22]);
158 vec
159 }
160 b'\\' => {
161 vec.extend_from_slice(&[0x5c, 0x5c]);
162 vec
163 }
164 b'\n' => {
165 vec.extend_from_slice(&[0x5c, 0x6e]);
166 vec
167 }
168 b'\r' => {
169 vec.extend_from_slice(&[0x5c, 0x72]);
170 vec
171 }
172 b'\t' => {
173 vec.extend_from_slice(&[0x5c, 0x74]);
174 vec
175 }
176 _ => {
177 vec.push(*ch);
178 vec
179 }
180 });
181 formatted.push(b'\"');
182 buf.push_str(unsafe { std::str::from_utf8_unchecked(&formatted) });
183 }
184}
185
186impl ToJson for i64 {
187 fn to_json(&self, buf: &mut String) {
188 buf.push_str(&self.to_string());
189 }
190}
191
192use super::ZOnce;
193
194impl ToJson for Dynamic {
195 fn to_json(&self, buf: &mut String) {
196 match self {
197 Self::Iter { idx: _, keys: _, value: _ } => {}
198 Self::Bool(b) => {
199 if *b {
200 buf.push_str("true")
201 } else {
202 buf.push_str("false")
203 }
204 }
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::Bytes(vec) => vec_to_json!(buf, vec, U8),
218 Self::VecI8(vec) => vec_to_json!(buf, vec, I8),
219 Self::VecU16(vec) => vec_to_json!(buf, vec, U16),
220 Self::VecI16(vec) => vec_to_json!(buf, vec, I16),
221 Self::VecU32(vec) => vec_to_json!(buf, vec, U32),
222 Self::VecI32(vec) => vec_to_json!(buf, vec, I32),
223 Self::VecF32(vec) => vec_to_json!(buf, vec, F32),
224 Self::VecU64(vec) => vec_to_json!(buf, vec, U64),
225 Self::VecI64(vec) => vec_to_json!(buf, vec, I64),
226 Self::VecF64(vec) => vec_to_json!(buf, vec, F64),
227 Self::List(a) => {
228 buf.push('[');
229 let mut once = ZOnce::new("", ",\n");
230 a.read().unwrap().iter().for_each(|item| {
231 buf.push_str(once.take());
232 item.to_json(buf);
233 });
234 buf.push(']');
235 }
236 Self::Map(map) => {
237 buf.push('{');
238 let mut once = ZOnce::new("", ",\n");
239 map.read().unwrap().iter().for_each(|(k, v)| {
240 buf.push_str(once.take());
241 k.as_str().to_json(buf);
242 buf.push_str(": ");
243 v.to_json(buf);
244 });
245 buf.push_str("}\n");
246 }
247 Self::Struct { .. } => {
248 buf.push('{');
249 let mut once = ZOnce::new("", ",\n");
250 self.keys().iter().for_each(|k| {
251 buf.push_str(once.take());
252 k.as_str().to_json(buf);
253 buf.push_str(": ");
254 self.get_dynamic(k).unwrap_or(Dynamic::Null).to_json(buf);
255 });
256 buf.push_str("}\n");
257 }
258 }
259 }
260}