1use super::{JsonParse, JsonParseError, JsonParsingContext, Parser, array, object};
2use crate::{JsonArrayBuf, JsonNumberBuf, JsonObject, JsonString, JsonValue, object::Key};
3use decoded_char::DecodedChar;
4
5#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
7pub enum Fragment {
8 Value(JsonValue),
9 BeginArray,
10 BeginObject((Key, usize)),
11}
12
13impl Fragment {
14 fn value_or_parse<C, E>(
15 value: Option<(JsonValue, usize)>,
16 parser: &mut Parser<C, E>,
17 context: JsonParsingContext,
18 ) -> Result<(Self, usize), JsonParseError<E>>
19 where
20 C: Iterator<Item = Result<DecodedChar, E>>,
21 {
22 match value {
23 Some((value, i)) => Ok((value.into(), i)),
24 None => Self::parse_in(parser, context),
25 }
26 }
27}
28
29impl From<JsonValue> for Fragment {
30 fn from(v: JsonValue) -> Self {
31 Self::Value(v)
32 }
33}
34
35impl JsonParse for Fragment {
36 fn parse_in<C, E>(
37 parser: &mut Parser<C, E>,
38 context: JsonParsingContext,
39 ) -> Result<(Self, usize), JsonParseError<E>>
40 where
41 C: Iterator<Item = Result<DecodedChar, E>>,
42 {
43 parser.skip_whitespaces()?;
44
45 let (value, i) = match parser.peek_char()? {
46 Some('n') => {
47 let ((), i) = <()>::parse_in(parser, context)?;
48 (JsonValue::Null, i)
49 }
50 Some('t' | 'f') => {
51 let (value, i) = bool::parse_in(parser, context)?;
52 (JsonValue::Boolean(value), i)
53 }
54 Some('0'..='9' | '-') => {
55 let (value, i) = JsonNumberBuf::parse_in(parser, context)?;
56 (JsonValue::Number(value), i)
57 }
58 Some('"') => {
59 let (value, i) = JsonString::parse_in(parser, context)?;
60 (JsonValue::String(value), i)
61 }
62 Some('[') => match array::StartFragment::parse_in(parser, context)? {
63 (array::StartFragment::Empty, span) => {
64 (JsonValue::Array(JsonArrayBuf::new()), span)
65 }
66 (array::StartFragment::NonEmpty, span) => return Ok((Self::BeginArray, span)),
67 },
68 Some('{') => match object::StartFragment::parse_in(parser, context)? {
69 (object::StartFragment::Empty, span) => {
70 (JsonValue::Object(JsonObject::new()), span)
71 }
72 (object::StartFragment::NonEmpty(key), span) => {
73 return Ok((Self::BeginObject(key), span));
74 }
75 },
76 unexpected => return Err(JsonParseError::unexpected(parser.position, unexpected)),
77 };
78
79 Ok((Self::Value(value), i))
80 }
81}
82
83impl JsonParse for JsonValue {
84 fn parse_in<C, E>(
85 parser: &mut Parser<C, E>,
86 context: JsonParsingContext,
87 ) -> Result<(Self, usize), JsonParseError<E>>
88 where
89 C: Iterator<Item = Result<DecodedChar, E>>,
90 {
91 enum StackItem {
92 Array((JsonArrayBuf, usize)),
93 ArrayItem((JsonArrayBuf, usize)),
94 Object((JsonObject, usize)),
95 ObjectEntry((JsonObject, usize), (Key, usize)),
96 }
97
98 let mut stack: Vec<StackItem> = vec![];
99 let mut value: Option<(JsonValue, usize)> = None;
100
101 fn stack_context(stack: &[StackItem], root: JsonParsingContext) -> JsonParsingContext {
102 match stack.last() {
103 Some(StackItem::Array(_) | StackItem::ArrayItem(_)) => JsonParsingContext::Array,
104 Some(StackItem::Object(_)) => JsonParsingContext::ObjectKey,
105 Some(StackItem::ObjectEntry(_, _)) => JsonParsingContext::ObjectValue,
106 None => root,
107 }
108 }
109
110 loop {
111 match stack.pop() {
112 None => match Fragment::value_or_parse(
113 value.take(),
114 parser,
115 stack_context(&stack, context),
116 )? {
117 (Fragment::Value(value), i) => {
118 parser.skip_whitespaces()?;
119 break match parser.next_char()? {
120 (p, Some(c)) => Err(JsonParseError::unexpected(p, Some(c))),
121 (_, None) => Ok((value, i)),
122 };
123 }
124 (Fragment::BeginArray, i) => {
125 stack.push(StackItem::ArrayItem((JsonArrayBuf::new(), i)))
126 }
127 (Fragment::BeginObject(key), i) => {
128 stack.push(StackItem::ObjectEntry((JsonObject::new(), i), key))
129 }
130 },
131 Some(StackItem::Array((array, i))) => {
132 match array::ContinueFragment::parse_in(parser, i)? {
133 array::ContinueFragment::Item => {
134 stack.push(StackItem::ArrayItem((array, i)))
135 }
136 array::ContinueFragment::End => value = Some((JsonValue::Array(array), i)),
137 }
138 }
139 Some(StackItem::ArrayItem((mut array, i))) => {
140 match Fragment::value_or_parse(value.take(), parser, JsonParsingContext::Array)?
141 {
142 (Fragment::Value(value), _) => {
143 array.push(value);
144 stack.push(StackItem::Array((array, i)));
145 }
146 (Fragment::BeginArray, j) => {
147 stack.push(StackItem::ArrayItem((array, i)));
148 stack.push(StackItem::ArrayItem((JsonArrayBuf::new(), j)))
149 }
150 (Fragment::BeginObject(value_key), j) => {
151 stack.push(StackItem::ArrayItem((array, i)));
152 stack.push(StackItem::ObjectEntry((JsonObject::new(), j), value_key))
153 }
154 }
155 }
156 Some(StackItem::Object((object, i))) => {
157 match object::ContinueFragment::parse_in(parser, i)? {
158 object::ContinueFragment::Entry(key) => {
159 stack.push(StackItem::ObjectEntry((object, i), key))
160 }
161 object::ContinueFragment::End => {
162 value = Some((JsonValue::Object(object), i))
163 }
164 }
165 }
166 Some(StackItem::ObjectEntry((mut object, i), (key, e))) => {
167 match Fragment::value_or_parse(
168 value.take(),
169 parser,
170 JsonParsingContext::ObjectValue,
171 )? {
172 (Fragment::Value(value), _) => {
173 parser.end_fragment(e);
174 object.push_back(key, value);
175 stack.push(StackItem::Object((object, i)));
176 }
177 (Fragment::BeginArray, j) => {
178 stack.push(StackItem::ObjectEntry((object, i), (key, e)));
179 stack.push(StackItem::ArrayItem((JsonArrayBuf::new(), j)))
180 }
181 (Fragment::BeginObject(value_key), j) => {
182 stack.push(StackItem::ObjectEntry((object, i), (key, e)));
183 stack.push(StackItem::ObjectEntry((JsonObject::new(), j), value_key))
184 }
185 }
186 }
187 }
188 }
189 }
190}