1use super::{
2 json_state::JsonState,
3 shared::{
4 to_js_string, DataType, JsonElement, JsonStackElement, JsonStackObject, ParseError,
5 ParseResult, ParsingStatus,
6 },
7};
8use crate::{
9 common::{cast::Cast, default::default},
10 js::{any::Any, js_array::new_array, js_object::new_object},
11 mem::manager::Manager,
12 tokenizer::JsonToken,
13};
14use std::collections::BTreeMap;
15
16pub struct AnySuccess<M: Manager> {
17 pub state: AnyState<M>,
18 pub value: Any<M::Dealloc>,
19}
20
21pub enum AnyResult<M: Manager> {
22 Continue(AnyState<M>),
23 Success(AnySuccess<M>),
24 Error(ParseError),
25}
26
27pub struct AnyState<M: Manager> {
28 pub data_type: DataType,
29 pub status: ParsingStatus,
30 pub current: JsonElement<M::Dealloc>,
31 pub stack: Vec<JsonStackElement<M::Dealloc>>,
32 pub consts: BTreeMap<String, Any<M::Dealloc>>,
33}
34
35impl<M: Manager> Default for AnyState<M> {
36 fn default() -> Self {
37 AnyState {
38 data_type: default(),
39 status: ParsingStatus::Initial,
40 current: JsonElement::None,
41 stack: [].cast(),
42 consts: default(),
43 }
44 }
45}
46
47impl<M: Manager> AnyState<M> {
49 pub fn set_djs(self) -> Self {
50 AnyState {
51 data_type: DataType::Djs,
52 ..self
53 }
54 }
55
56 pub fn set_mjs(self) -> Self {
57 AnyState {
58 data_type: DataType::Mjs,
59 ..self
60 }
61 }
62
63 pub fn set_cjs(self) -> Self {
64 AnyState {
65 data_type: DataType::Cjs,
66 ..self
67 }
68 }
69
70 pub fn parse(
71 self,
72 manager: M,
73 token: JsonToken<M::Dealloc>,
74 ) -> (
75 AnyResult<M>,
76 Option<String>,
77 ) {
78 match self.status {
79 ParsingStatus::Initial | ParsingStatus::ObjectColon => {
80 (self.parse_value(manager, token), None)
81 }
82 ParsingStatus::ArrayBegin => (self.parse_array_begin(manager, token), None),
83 ParsingStatus::ArrayValue => (self.parse_array_value(manager, token), None),
84 ParsingStatus::ArrayComma => (self.parse_array_comma(manager, token), None),
85 ParsingStatus::ObjectBegin => (self.parse_object_begin(manager, token), None),
86 ParsingStatus::ObjectKey => (self.parse_object_key(token), None),
87 ParsingStatus::ObjectValue => (self.parse_object_next(manager, token), None),
88 ParsingStatus::ObjectComma => (self.parse_object_comma(manager, token), None),
89 ParsingStatus::ImportBegin => (self.parse_import_begin(token), None),
90 ParsingStatus::ImportValue => self.parse_import_value(token),
91 ParsingStatus::ImportEnd => (self.parse_import_end(token), None),
92 }
93 }
94
95 pub fn parse_for_module(
96 self,
97 manager: M,
98 token: JsonToken<M::Dealloc>,
99 ) -> (
100 JsonState<M>,
101 Option<String>,
102 ) {
103 let (any_result, module_name) = self.parse(manager, token);
104 match module_name {
105 Some(module_name) => {
106 if let AnyResult::Continue(state) = any_result {
107 (JsonState::ParseModule(state), Some(module_name))
108 } else {
109 panic!("Import path should be returned only with Continue result");
110 }
111 }
112 None => match any_result {
113 AnyResult::Continue(state) => (JsonState::ParseModule(state), None),
114 AnyResult::Success(success) => (
115 JsonState::Result(ParseResult {
116 data_type: success.state.data_type,
117 any: success.value,
118 }),
119 None,
120 ),
121 AnyResult::Error(error) => (JsonState::Error(error), None),
122 },
123 }
124 }
125
126 pub fn parse_import_begin(self, token: JsonToken<M::Dealloc>) -> AnyResult<M> {
127 match token {
128 JsonToken::OpeningParenthesis => AnyResult::Continue(AnyState {
129 status: ParsingStatus::ImportValue,
130 ..self
131 }),
132 _ => AnyResult::Error(ParseError::WrongRequireStatement),
133 }
134 }
135
136 pub fn parse_import_end(self, token: JsonToken<M::Dealloc>) -> AnyResult<M> {
137 match token {
138 JsonToken::ClosingParenthesis => self.end_import(),
139 _ => AnyResult::Error(ParseError::WrongRequireStatement),
140 }
141 }
142
143 fn parse_import_value(
144 self,
145 token: JsonToken<M::Dealloc>,
146 ) -> (
147 AnyResult<M>,
148 Option<String>,
149 ) {
150 match token {
151 JsonToken::String(s) => (
152 AnyResult::Continue(AnyState {
153 status: ParsingStatus::ImportEnd,
154 ..self
155 }),
156 Some(s),
157 ),
158 _ => (AnyResult::Error(ParseError::WrongRequireStatement), None),
159 }
160 }
161
162 pub fn begin_import(mut self) -> AnyResult<M> {
163 if let JsonElement::Stack(top) = self.current {
164 self.stack.push(top);
165 }
166 AnyResult::Continue(AnyState {
167 data_type: DataType::Cjs,
168 status: ParsingStatus::ImportBegin,
169 current: JsonElement::None,
170 ..self
171 })
172 }
173
174 pub fn end_import(mut self) -> AnyResult<M> {
175 match self.current {
176 JsonElement::Any(any) => {
177 let current = match self.stack.pop() {
178 Some(element) => JsonElement::Stack(element),
179 None => JsonElement::None,
180 };
181 let new_state = AnyState {
182 status: ParsingStatus::Initial,
183 current,
184 ..self
185 };
186 new_state.push_value(any)
187 }
188 _ => unreachable!(),
189 }
190 }
191
192 pub fn parse_value(self, manager: M, token: JsonToken<M::Dealloc>) -> AnyResult<M> {
193 match token {
194 JsonToken::ArrayBegin => self.begin_array(),
195 JsonToken::ObjectBegin => self.begin_object(),
196 JsonToken::Id(s) if self.data_type.is_cjs_compatible() && s == "require" => {
197 self.begin_import()
198 }
199 _ => {
200 let option_any = token.try_to_any(manager, &self.consts);
201 match option_any {
202 Some(any) => self.push_value(any),
203 None => AnyResult::Error(ParseError::UnexpectedToken),
204 }
205 }
206 }
207 }
208
209 pub fn push_value(self, value: Any<M::Dealloc>) -> AnyResult<M> {
210 match self.current {
211 JsonElement::None => AnyResult::Success(AnySuccess {
212 state: AnyState {
213 status: ParsingStatus::Initial,
214 ..self
215 },
216 value,
217 }),
218 JsonElement::Stack(top) => match top {
219 JsonStackElement::Array(mut arr) => {
220 arr.push(value);
221 AnyResult::Continue(AnyState {
222 status: ParsingStatus::ArrayValue,
223 current: JsonElement::Stack(JsonStackElement::Array(arr)),
224 ..self
225 })
226 }
227 JsonStackElement::Object(mut stack_obj) => {
228 stack_obj.map.insert(stack_obj.key, value);
229 let new_stack_obj = JsonStackObject {
230 map: stack_obj.map,
231 key: String::default(),
232 };
233 AnyResult::Continue(AnyState {
234 status: ParsingStatus::ObjectValue,
235 current: JsonElement::Stack(JsonStackElement::Object(new_stack_obj)),
236 ..self
237 })
238 }
239 },
240 _ => todo!(),
241 }
242 }
243
244 pub fn push_key(self, s: String) -> AnyResult<M> {
245 match self.current {
246 JsonElement::Stack(JsonStackElement::Object(stack_obj)) => {
247 let new_stack_obj = JsonStackObject {
248 map: stack_obj.map,
249 key: s,
250 };
251 AnyResult::Continue(AnyState {
252 status: ParsingStatus::ObjectKey,
253 current: JsonElement::Stack(JsonStackElement::Object(new_stack_obj)),
254 ..self
255 })
256 }
257 _ => AnyResult::Error(ParseError::UnexpectedToken),
258 }
259 }
260
261 pub fn parse_array_comma(self, manager: M, token: JsonToken<M::Dealloc>) -> AnyResult<M> {
262 match token {
263 JsonToken::ArrayBegin => self.begin_array(),
264 JsonToken::ObjectBegin => self.begin_object(),
265 JsonToken::Id(s) if self.data_type == DataType::Cjs && s == "require" => {
266 self.begin_import()
267 }
268 JsonToken::ArrayEnd => self.end_array(manager),
269 _ => {
270 let option_any = token.try_to_any(manager, &self.consts);
271 match option_any {
272 Some(any) => self.push_value(any),
273 None => AnyResult::Error(ParseError::UnexpectedToken),
274 }
275 }
276 }
277 }
278
279 pub fn parse_array_begin(self, manager: M, token: JsonToken<M::Dealloc>) -> AnyResult<M> {
280 match token {
281 JsonToken::ArrayBegin => self.begin_array(),
282 JsonToken::ArrayEnd => self.end_array(manager),
283 JsonToken::ObjectBegin => self.begin_object(),
284 _ => {
285 let option_any = token.try_to_any(manager, &self.consts);
286 match option_any {
287 Some(any) => self.push_value(any),
288 None => AnyResult::Error(ParseError::UnexpectedToken),
289 }
290 }
291 }
292 }
293
294 pub fn parse_array_value(self, manager: M, token: JsonToken<M::Dealloc>) -> AnyResult<M> {
295 match token {
296 JsonToken::ArrayEnd => self.end_array(manager),
297 JsonToken::Comma => AnyResult::Continue(AnyState {
298 status: ParsingStatus::ArrayComma,
299 ..self
300 }),
301 _ => AnyResult::Error(ParseError::UnexpectedToken),
302 }
303 }
304
305 pub fn begin_array(mut self) -> AnyResult<M> {
306 let new_top = JsonStackElement::Array(Vec::default());
307 if let JsonElement::Stack(top) = self.current {
308 self.stack.push(top);
309 }
310 AnyResult::Continue(AnyState {
311 status: ParsingStatus::ArrayBegin,
312 current: JsonElement::Stack(new_top),
313 ..self
314 })
315 }
316
317 pub fn end_array(mut self, manager: M) -> AnyResult<M> {
318 match self.current {
319 JsonElement::Stack(JsonStackElement::Array(array)) => {
320 let js_array = new_array(manager, array).to_ref();
321 let current = match self.stack.pop() {
322 Some(element) => JsonElement::Stack(element),
323 None => JsonElement::None,
324 };
325 let new_state = AnyState { current, ..self };
326 new_state.push_value(Any::move_from(js_array))
327 }
328 _ => unreachable!(),
329 }
330 }
331
332 pub fn parse_object_begin(self, manager: M, token: JsonToken<M::Dealloc>) -> AnyResult<M> {
333 match token {
334 JsonToken::String(s) => self.push_key(s),
335 JsonToken::Id(s) if self.data_type.is_djs() => self.push_key(s),
336 JsonToken::ObjectEnd => self.end_object(manager),
337 _ => AnyResult::Error(ParseError::UnexpectedToken),
338 }
339 }
340
341 pub fn parse_object_next(self, manager: M, token: JsonToken<M::Dealloc>) -> AnyResult<M> {
342 match token {
343 JsonToken::ObjectEnd => self.end_object(manager),
344 JsonToken::Comma => AnyResult::Continue(AnyState {
345 status: ParsingStatus::ObjectComma,
346 ..self
347 }),
348 _ => AnyResult::Error(ParseError::UnexpectedToken),
349 }
350 }
351
352 pub fn parse_object_comma(self, manager: M, token: JsonToken<M::Dealloc>) -> AnyResult<M> {
353 match token {
354 JsonToken::String(s) => self.push_key(s),
355 JsonToken::ObjectEnd => self.end_object(manager),
356 _ => AnyResult::Error(ParseError::UnexpectedToken),
357 }
358 }
359
360 pub fn parse_object_key(self, token: JsonToken<M::Dealloc>) -> AnyResult<M> {
361 match token {
362 JsonToken::Colon => AnyResult::Continue(AnyState {
363 status: ParsingStatus::ObjectColon,
364 ..self
365 }),
366 _ => AnyResult::Error(ParseError::UnexpectedToken),
367 }
368 }
369
370 pub fn begin_object(mut self) -> AnyResult<M> {
371 let new_top: JsonStackElement<M::Dealloc> = JsonStackElement::Object(JsonStackObject {
372 map: BTreeMap::default(),
373 key: String::default(),
374 });
375 if let JsonElement::Stack(top) = self.current {
376 self.stack.push(top)
377 }
378 AnyResult::Continue(AnyState {
379 status: ParsingStatus::ObjectBegin,
380 current: JsonElement::Stack(new_top),
381 ..self
382 })
383 }
384
385 pub fn end_object(mut self, manager: M) -> AnyResult<M> {
386 match self.current {
387 JsonElement::Stack(JsonStackElement::Object(object)) => {
388 let vec = object
389 .map
390 .into_iter()
391 .map(|kv| (to_js_string(manager, kv.0), kv.1))
392 .collect::<Vec<_>>();
393 let js_object = new_object(manager, vec).to_ref();
394 let current = match self.stack.pop() {
395 Some(element) => JsonElement::Stack(element),
396 None => JsonElement::None,
397 };
398 let new_state = AnyState { current, ..self };
399 new_state.push_value(Any::move_from(js_object))
400 }
401 _ => unreachable!(),
402 }
403 }
404}