1use crate::builder::{ArrBuilder, BuildResult, NumberError, ObjBuilder};
4use crate::{
5 ArrayBuilder, ArrayRefBuilder, BuildError, Number, ObjectBuilder, ObjectRefBuilder, Scalar, Yason, YasonBuf,
6};
7use decimal_rs::DecimalParseError;
8use serde_json::{Map, Value};
9use std::fmt::Write;
10use std::str::FromStr;
11
12impl TryFrom<&serde_json::Value> for YasonBuf {
13 type Error = BuildError;
14
15 #[inline]
16 fn try_from(value: &serde_json::Value) -> Result<Self, Self::Error> {
17 let mut buf = String::new();
18 match value {
19 Value::Null => Scalar::null(),
20 Value::Bool(val) => Scalar::bool(*val),
21 Value::Number(val) => Scalar::number(number2decimal(val, &mut buf)?),
22 Value::String(val) => Scalar::string(val),
23 Value::Array(val) => {
24 let mut array_builder = ArrayBuilder::try_new(val.len() as u16)?;
25 write_array(&mut array_builder, val, &mut buf)?;
26 array_builder.finish()
27 }
28 Value::Object(val) => {
29 let mut object_builder = ObjectBuilder::try_new(val.len() as u16, false)?;
30 write_object(&mut object_builder, val, &mut buf)?;
31 object_builder.finish()
32 }
33 }
34 }
35}
36
37impl YasonBuf {
38 #[inline]
40 pub fn parse<T: AsRef<str>>(str: T) -> BuildResult<Self> {
41 let json: Value = serde_json::from_str(str.as_ref()).map_err(BuildError::JsonError)?;
42 YasonBuf::try_from(&json)
43 }
44}
45
46impl Yason {
47 #[inline]
49 pub fn parse_to<T: AsRef<str>>(bytes: &mut Vec<u8>, str: T) -> BuildResult<&Yason> {
50 let mut buf = String::new();
51
52 let json: Value = serde_json::from_str(str.as_ref()).map_err(BuildError::JsonError)?;
53 match &json {
54 Value::Null => Scalar::null_with_vec(bytes),
55 Value::Bool(val) => Scalar::bool_with_vec(*val, bytes),
56 Value::Number(val) => Scalar::number_with_vec(number2decimal(val, &mut buf)?, bytes),
57 Value::String(val) => Scalar::string_with_vec(val, bytes),
58 Value::Array(array) => {
59 let mut builder = ArrayRefBuilder::try_new(bytes, array.len() as u16)?;
60 write_array(&mut builder, array, &mut buf)?;
61 builder.finish()
62 }
63 Value::Object(object) => {
64 let mut builder = ObjectRefBuilder::try_new(bytes, object.len() as u16, false)?;
65 write_object(&mut builder, object, &mut buf)?;
66 builder.finish()
67 }
68 }
69 }
70}
71
72#[inline]
73fn write_array<T: ArrBuilder>(builder: &mut T, array: &[serde_json::Value], buf: &mut String) -> BuildResult<()> {
74 for value in array {
75 match value {
76 Value::Null => {
77 builder.push_null()?;
78 }
79 Value::Bool(val) => {
80 builder.push_bool(*val)?;
81 }
82 Value::Number(val) => {
83 builder.push_number(number2decimal(val, buf)?)?;
84 }
85 Value::String(val) => {
86 builder.push_string(val)?;
87 }
88 Value::Array(val) => {
89 let mut array_builder = builder.push_array(val.len() as u16)?;
90 write_array(&mut array_builder, val, buf)?;
91 array_builder.finish()?;
92 }
93 Value::Object(val) => {
94 let mut object_builder = builder.push_object(val.len() as u16, false)?;
95 write_object(&mut object_builder, val, buf)?;
96 object_builder.finish()?;
97 }
98 }
99 }
100 Ok(())
101}
102
103#[inline]
104fn write_object<T: ObjBuilder>(
105 builder: &mut T,
106 object: &Map<String, serde_json::Value>,
107 buf: &mut String,
108) -> BuildResult<()> {
109 for (key, value) in object {
110 match value {
111 Value::Null => {
112 builder.push_null(key)?;
113 }
114 Value::Bool(val) => {
115 builder.push_bool(key, *val)?;
116 }
117 Value::Number(val) => {
118 builder.push_number(key, number2decimal(val, buf)?)?;
119 }
120 Value::String(val) => {
121 builder.push_string(key, val)?;
122 }
123 Value::Array(val) => {
124 let mut array_builder = builder.push_array(key, val.len() as u16)?;
125 write_array(&mut array_builder, val, buf)?;
126 array_builder.finish()?;
127 }
128 Value::Object(val) => {
129 let mut object_builder = builder.push_object(key, val.len() as u16, false)?;
130 write_object(&mut object_builder, val, buf)?;
131 object_builder.finish()?;
132 }
133 }
134 }
135 Ok(())
136}
137
138#[inline]
139fn number2decimal(val: &serde_json::Number, buf: &mut String) -> BuildResult<Number> {
140 buf.clear();
141 buf.try_reserve(256)?;
142 write!(buf, "{}", val).map_err(|_| BuildError::NumberError(NumberError::FormatError))?;
143 Number::from_str(buf.as_str()).map_or_else(
144 |e| match e {
145 DecimalParseError::Underflow => Ok(Number::ZERO),
146 DecimalParseError::Overflow => Err(BuildError::NumberError(NumberError::Overflow)),
147 _ => unreachable!("internal error: entered unreachable parsing error"),
148 },
149 Ok,
150 )
151}
152
153#[cfg(test)]
154mod tests {
155 use super::*;
156 use decimal_rs::Decimal;
157 use serde_json::Error;
158 use std::str::FromStr;
159
160 #[test]
161 fn test_number2decimal() {
162 fn assert_number(input: &str, output: &str) {
163 let number: serde_json::Number = serde_json::from_str(input).unwrap();
164 let mut buf = String::with_capacity(256);
165 let decimal = number2decimal(&number, &mut buf).unwrap();
166 assert_eq!(decimal, Decimal::from_str(output).unwrap());
167 }
168
169 fn assert_number_invalid(s: &str) {
170 let number: Result<serde_json::Number, Error> = serde_json::from_str(s);
171 assert!(number.is_err());
172 }
173
174 fn assert_number_overflow(s: &str) {
175 let number: serde_json::Number = serde_json::from_str(s).unwrap();
176 let mut buf = String::with_capacity(256);
177 let decimal = number2decimal(&number, &mut buf);
178 match decimal {
179 Err(BuildError::NumberError(NumberError::Overflow)) => {}
180 _ => panic!("expected numeric overflow"),
181 };
182 }
183
184 assert_number_invalid("Nan");
185 assert_number_invalid("Inf");
186 assert_number_invalid("-Inf");
187 assert_number_invalid("123abc");
188 assert_number_invalid("");
189 assert_number_invalid(" ");
190
191 assert_number_overflow("1e126");
192 assert_number_overflow("1e150");
193
194 assert_number("-123", "-123");
195 assert_number("0", "0");
196 assert_number("123", "123");
197
198 assert_number("9007199254740991", "9007199254740991"); assert_number("-9007199254740991", "-9007199254740991"); assert_number("9007199254740993", "9007199254740993"); assert_number("-9007199254740993", "-9007199254740993"); assert_number("18446744073709551616", "18446744073709551616"); assert_number("1e125", "1e125");
205 assert_number("1e-130", "1e-130");
206 assert_number("1e-131", "0");
207 assert_number("1e-150", "0");
208
209 assert_number(
210 "222222222222222222222222222222222222222222",
211 "222222222222222222222222222222222222222200",
212 ); assert_number(
214 "555555555555555555555555555555555555555555",
215 "555555555555555555555555555555555555555600",
216 ); assert_number(
219 "0.222222222222222222222222222222222222222222",
220 "0.2222222222222222222222222222222222222222",
221 ); assert_number(
223 "0.555555555555555555555555555555555555555555",
224 "0.5555555555555555555555555555555555555556",
225 ); assert_number(
228 "0.000000222222222222222222222222222222222222222222",
229 "0.0000002222222222222222222222222222222222222222",
230 ); assert_number(
232 "0.000000555555555555555555555555555555555555555555",
233 "0.0000005555555555555555555555555555555555555556",
234 ); assert_number(
237 "222222222222222222222222.222222222222222222222e50",
238 "22222222222222222222222222222222222222e36",
239 ); assert_number(
241 "555555555555555555555555.555555555555555555555e50",
242 "55555555555555555555555555555555555556e36",
243 ); }
245}