simple_json2/
json.rs

1extern crate alloc;
2use alloc::{vec::Vec, string::String as AllocString};
3
4use crate::parser::{
5	Concat, Concat3, Either, Error, Input, OneOf, OneOrMore, Parser, ResultOf, ZeroOrMore,
6	ZeroOrOne,
7};
8use crate::{ literals, parsers, impls::SimpleError };
9use core::{ convert::TryInto, fmt::Debug };
10
11#[cfg(not(feature = "std"))]
12use num_traits::{ float::FloatCore };
13
14literals! {
15	pub WhitespaceChar => '\u{0020}' | '\u{000D}' | '\u{000A}' | '\u{0009}';
16	pub SignChar => '+' | '-';
17	pub NegativeSignChar => '-';
18	pub EChar => 'E' | 'e';
19	pub OneToNineChar => '1' ..= '9';
20	pub DigitChar => '0' ..= '9';
21	pub DotChar => '.';
22	pub HexChar => '0' ..= '9' | 'a' ..= 'f' | 'A' ..= 'F';
23	pub DoubleQuoteChar => '"';
24	pub OpenCurlyBracketChar => '{';
25	pub CloseCurlyBracketChar => '}';
26	pub CommaChar => ',';
27	pub OpenSquareBracketChar => '[';
28	pub CloseSquareBracketChar => ']';
29}
30
31pub type Whitespace = ZeroOrMore<WhitespaceChar>;
32
33pub type Sign = ZeroOrOne<SignChar>;
34
35pub type Digits = OneOrMore<DigitChar>;
36
37parsers! {
38	pub PositiveInteger = OneOf<Concat<OneToNineChar, Digits>, DigitChar>, u64, (output) => {
39		match output {
40			Either::A((c, cs)) => {
41				let mut val = c.to_digit(10).unwrap() as u64;
42				for c in cs {
43					val *= 10;
44					val += c.to_digit(10).unwrap() as u64;
45				}
46				val
47			},
48			Either::B(c) => c.to_digit(10).unwrap() as u64,
49		}
50	};
51
52	pub NegativeInteger = Concat<NegativeSignChar, PositiveInteger>, i64, (output) => {
53		let (_, output) = output;
54		- (output as i64)
55	};
56
57	pub Integer = OneOf<PositiveInteger, NegativeInteger>, i64, (output) => {
58		match output {
59			Either::A(a) => a as i64,
60			Either::B(b) => b,
61		}
62	};
63
64	pub Fraction = ZeroOrOne<Concat<DotChar, Digits>>, (u64, u32), (output) => {
65		match output {
66			Either::A((_, cs)) => {
67				let mut val = 0u64;
68				let len = cs.len();
69				for c in cs {
70					val *= 10u64;
71					val += c.to_digit(10).unwrap() as u64;
72				}
73				(val, len as u32)
74			},
75			Either::B(_) => (0u64, 0u32),
76		}
77	};
78
79	pub Exponent = ZeroOrOne<Concat3<EChar, Sign, Digits>>, i32, (output) => {
80		match output {
81			Either::A((_, (s, cs))) => {
82				let mul = if let Either::A('-') = s { -1 } else { 1 };
83				let mut val = 0i32;
84				for c in cs {
85					val *= 10;
86					val += c.to_digit(10).unwrap() as i32;
87				}
88				val * mul
89			},
90			Either::B(_) => 0,
91		}
92	};
93
94	pub Number = Concat3<Integer, Fraction, Exponent>, NumberValue, (output) => {
95		let (n, (f, e)) = output;
96		NumberValue {
97			integer: n,
98			fraction: f.0,
99			fraction_length: f.1,
100			exponent: e,
101		}
102	};
103
104	pub Hex = HexChar, u8, (output) => {
105		output.to_digit(16).unwrap() as u8
106	};
107
108	pub String = Concat3<DoubleQuoteChar, Characters, DoubleQuoteChar>, Vec<char>, (output) => {
109		match (output.1).0 {
110			Either::A(bytes) => bytes,
111			Either::B(_) => Vec::new(),
112		}
113	};
114}
115
116pub struct Escape;
117
118impl<I: Input> Parser<I> for Escape {
119	type Output = char;
120	fn parse(input: &I, current: I::Position) -> ResultOf<I, Self::Output> {
121		let (c, next) = input
122			.next(current)
123			.map_err(|e| e.add_reason(Some(current), "Escape"))?;
124		match c {
125			'"' | '\\' | '/' | 'b' | 'f' | 'n' | 'r' | 't' => Ok((c, next)),
126			'u' => {
127				let (b1, next) = <Hex as Parser<I>>::parse(input, next)?;
128				let (b2, next) = <Hex as Parser<I>>::parse(input, next)?;
129				let (b3, next) = <Hex as Parser<I>>::parse(input, next)?;
130				let (b4, next) = <Hex as Parser<I>>::parse(input, next)?;
131				let byte = (b1 as u32) << 24 | (b2 as u32) << 16 | (b3 as u32) << 8 | (b4 as u32);
132				let c = byte
133					.try_into()
134					.map_err(|_| input.error_at(current, "Escape"))?;
135				Ok((c, next))
136			}
137			_ => Err(input.error_at(current, "Escape")),
138		}
139	}
140}
141
142pub struct Character;
143
144impl<I: Input> Parser<I> for Character {
145	type Output = char;
146	fn parse(input: &I, current: I::Position) -> ResultOf<I, Self::Output> {
147		let (c, next) = input
148			.next(current)
149			.map_err(|e| e.add_reason(Some(current), "Character"))?;
150		match c {
151			'\\' => <Escape as Parser<I>>::parse(input, next),
152			'"' => Err(input.error_at(current, "Character")),
153			_ => Ok((c, next)),
154		}
155	}
156}
157
158pub type Characters = ZeroOrMore<Character>;
159
160pub struct Member;
161
162impl<I: Input> Parser<I> for Member {
163	type Output = (Vec<char>, JsonValue);
164	fn parse(input: &I, current: I::Position) -> ResultOf<I, Self::Output> {
165		let (_, next) = <Whitespace as Parser<I>>::parse(input, current)?;
166		let (key, next) = <String as Parser<I>>::parse(input, next)?;
167		let (_, next) = <Whitespace as Parser<I>>::parse(input, next)?;
168		let next = input
169			.next(next)
170			.and_then(|(c, next)| {
171				if c == ':' {
172					Ok(next)
173				} else {
174					Err(input.error_at(next, "Character"))
175				}
176			})
177			.map_err(|e| e.add_reason(Some(current), "Member"))?;
178		let (value, next) = <Element as Parser<I>>::parse(input, next)?;
179		Ok(((key, value), next))
180	}
181}
182
183pub struct Element;
184
185impl<I: Input> Parser<I> for Element {
186	type Output = JsonValue;
187	fn parse(input: &I, current: I::Position) -> ResultOf<I, Self::Output> {
188		let (_, next) = <Whitespace as Parser<I>>::parse(input, current)?;
189		let (output, next) = <Value as Parser<I>>::parse(input, next)?;
190		let (_, next) = <Whitespace as Parser<I>>::parse(input, next)?;
191		Ok((output, next))
192	}
193}
194
195pub struct Value;
196
197#[derive(Debug, Clone, PartialEq)]
198pub struct NumberValue {
199	pub integer: i64,
200	pub fraction: u64,
201	pub fraction_length: u32,
202	pub exponent: i32,
203}
204
205impl Into<f64> for NumberValue {
206	fn into(self) -> f64 {
207	(self.integer as f64 + self.fraction as f64 / 10f64.powi(self.fraction_length as i32))
208		* 10f64.powi(self.exponent)
209	}
210}
211
212pub type JsonObject = Vec<(Vec<char>, JsonValue)>;
213
214#[derive(Debug, Clone, PartialEq)]
215pub enum JsonValue {
216	Object(JsonObject),
217	Array(Vec<JsonValue>),
218	String(Vec<char>),
219	Number(NumberValue),
220	Boolean(bool),
221	Null,
222}
223
224impl JsonValue {
225	pub fn get_object(&self) -> Result<&JsonObject, SimpleError> {
226		if let JsonValue::Object(obj) = self {
227			return Ok(&obj);
228		}
229		Err(SimpleError::plain_str("get_object error"))
230	}
231
232	pub fn get_array(&self) -> Result<&Vec<JsonValue>, SimpleError> {
233		if let JsonValue::Array(vec) = self {
234			return Ok(&vec);
235		}
236		Err(SimpleError::plain_str("get_array error"))
237	}
238
239	pub fn get_string(&self) -> Result<AllocString, SimpleError> {
240		if let JsonValue::String(val) = self {
241			return Ok(val.iter().collect::<AllocString>());
242		}
243		Err(SimpleError::plain_str("get_string error"))
244	}
245
246	pub fn get_chars(&self) -> Result<Vec<char>, SimpleError> {
247		if let JsonValue::String(val) = self {
248			return Ok(val.iter().map(|c| *c).collect::<Vec<char>>());
249		}
250		Err(SimpleError::plain_str("get_chars error"))
251	}
252
253	pub fn get_bytes(&self) -> Result<Vec<u8>, SimpleError> {
254		if let JsonValue::String(val) = self {
255			return Ok(val.iter().map(|c| *c as u8).collect::<Vec<_>>());
256		}
257		Err(SimpleError::plain_str("get_bytes error"))
258	}
259
260	pub fn get_number_f64(&self) -> Result<f64, SimpleError> {
261		if let JsonValue::Number(val) = self {
262			return Ok(val.clone().into());
263		}
264		Err(SimpleError::plain_str("get_number_f64 error"))
265	}
266
267	pub fn get_bool(&self) -> Result<bool, SimpleError> {
268		if let JsonValue::Boolean(val) = self {
269			return Ok(*val);
270		}
271		Err(SimpleError::plain_str("get_bool error"))
272	}
273
274	pub fn is_null(&self) -> bool {
275		if let JsonValue::Null = self {
276			return true;
277		}
278		false
279	}
280}
281
282impl<I: Input> Parser<I> for Value
283where
284	I::Position: Copy,
285{
286	type Output = JsonValue;
287	fn parse(input: &I, current: I::Position) -> ResultOf<I, Self::Output> {
288		if let Ok((output, next)) = <Object as Parser<I>>::parse(input, current) {
289			return Ok((JsonValue::Object(output), next));
290		}
291		if let Ok((output, next)) = <Array as Parser<I>>::parse(input, current) {
292			return Ok((JsonValue::Array(output), next));
293		}
294		if let Ok((output, next)) = <String as Parser<I>>::parse(input, current) {
295			return Ok((JsonValue::String(output), next));
296		}
297		if let Ok((output, next)) = <Number as Parser<I>>::parse(input, current) {
298			return Ok((JsonValue::Number(output), next));
299		}
300		let (value, next) = input.next_range(current, 4)?;
301		if value == "null" {
302			return Ok((JsonValue::Null, next));
303		}
304		if value == "true" {
305			return Ok((JsonValue::Boolean(true), next));
306		}
307		let (value, next) = input.next_range(current, 5)?;
308		if value == "false" {
309			return Ok((JsonValue::Boolean(false), next));
310		}
311		Err(input.error_at(current, "Value"))
312	}
313}
314
315pub struct Object;
316
317impl<I: Input> Parser<I> for Object {
318	type Output = JsonObject;
319	fn parse(input: &I, current: I::Position) -> ResultOf<I, Self::Output> {
320		let (_, next) = <OpenCurlyBracketChar as Parser<I>>::parse(input, current)?;
321		let (output, next) = <OneOf<Members, Whitespace> as Parser<I>>::parse(input, next)?;
322		let (_, next) = <CloseCurlyBracketChar as Parser<I>>::parse(input, next)?;
323		let output = match output {
324			Either::A(a) => a,
325			Either::B(_) => Vec::new(),
326		};
327		Ok((output, next))
328	}
329}
330
331pub struct Members;
332
333impl<I: Input> Parser<I> for Members {
334	type Output = Vec<(Vec<char>, JsonValue)>;
335	fn parse(input: &I, current: I::Position) -> ResultOf<I, Self::Output> {
336		let (output, next) = <Member as Parser<I>>::parse(input, current)?;
337		let (rest, next) =
338			<ZeroOrMore<Concat<CommaChar, Member>> as Parser<I>>::parse(input, next)?;
339		let mut result = Vec::new();
340		result.push(output);
341		if let Either::A(rest) = rest {
342			result.extend(rest.into_iter().map(|(_, m)| m))
343		}
344		Ok((result, next))
345	}
346}
347
348pub struct Elements;
349
350impl<I: Input> Parser<I> for Elements {
351	type Output = Vec<JsonValue>;
352	fn parse(input: &I, current: I::Position) -> ResultOf<I, Self::Output> {
353		let (output, next) = <Element as Parser<I>>::parse(input, current)?;
354		let (rest, next) =
355			<ZeroOrMore<Concat<CommaChar, Element>> as Parser<I>>::parse(input, next)?;
356		let mut result = Vec::new();
357		result.push(output);
358		if let Either::A(rest) = rest {
359			result.extend(rest.into_iter().map(|(_, m)| m))
360		}
361		Ok((result, next))
362	}
363}
364
365pub struct Array;
366
367impl<I: Input> Parser<I> for Array {
368	type Output = Vec<JsonValue>;
369	fn parse(input: &I, current: I::Position) -> ResultOf<I, Self::Output> {
370		let (_, next) = <OpenSquareBracketChar as Parser<I>>::parse(input, current)?;
371		let (res, next) = <Elements as Parser<I>>::parse(input, next)?;
372		let (_, next) = <CloseSquareBracketChar as Parser<I>>::parse(input, next)?;
373		Ok((res, next))
374	}
375}
376
377pub type Json = Element;