1use crate::{
2 big_numbers::big_int::{BigInt, Sign},
3 common::default::default,
4 js::{
5 any::Any,
6 js_bigint::{new_bigint, JsBigintRef},
7 js_string::{new_string, JsStringRef},
8 null::Null,
9 },
10 mem::manager::{Dealloc, Manager},
11 tokenizer::JsonToken,
12};
13use std::collections::{BTreeMap, BTreeSet};
14use std::fmt::Display;
15
16#[derive(Debug, Default, PartialEq)]
17pub enum DataType {
18 #[default]
19 Json,
20 Djs,
21 Cjs,
22 Mjs,
23}
24
25impl DataType {
26 pub fn to_djs(&self) -> DataType {
27 match self {
28 DataType::Json | DataType::Djs => DataType::Djs,
29 DataType::Cjs => DataType::Cjs,
30 DataType::Mjs => DataType::Mjs,
31 }
32 }
33
34 pub fn is_djs(&self) -> bool {
35 matches!(self, DataType::Djs | DataType::Cjs | DataType::Mjs)
36 }
37
38 pub fn is_cjs_compatible(&self) -> bool {
39 matches!(self, DataType::Json | DataType::Djs | DataType::Cjs)
40 }
41
42 pub fn is_mjs_compatible(&self) -> bool {
43 matches!(self, DataType::Json | DataType::Djs | DataType::Mjs)
44 }
45}
46
47#[derive(Default, Debug)]
48pub enum ParsingStatus {
49 #[default]
50 Initial,
51 ArrayBegin,
52 ArrayValue,
53 ArrayComma,
54 ObjectBegin,
55 ObjectKey,
56 ObjectColon,
57 ObjectValue,
58 ObjectComma,
59 ImportBegin,
60 ImportValue,
61 ImportEnd,
62}
63
64#[derive(Debug, PartialEq)]
65pub enum ParseError {
66 UnexpectedToken,
67 UnexpectedEnd,
68 WrongExportStatement,
69 WrongConstStatement,
70 WrongRequireStatement,
71 WrongImportStatement,
72 CannotReadFile,
73 CircularDependency,
74 NewLineExpected,
75}
76
77impl Display for ParseError {
78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79 f.write_str(match self {
80 ParseError::UnexpectedToken => "UnexpectedToken",
81 ParseError::UnexpectedEnd => "UnexpectedEnd",
82 ParseError::WrongExportStatement => "WrongExportStatement",
83 ParseError::WrongConstStatement => "WrongConstStatement",
84 ParseError::WrongRequireStatement => "WrongRequireStatement",
85 ParseError::WrongImportStatement => "WrongImportStatement",
86 ParseError::CannotReadFile => "CannotReadFile",
87 ParseError::CircularDependency => "CircularDependency",
88 ParseError::NewLineExpected => "NewLineExpected",
89 })
90 }
91}
92
93pub struct ModuleCache<D: Dealloc> {
94 pub complete: BTreeMap<String, Any<D>>,
95 pub progress: BTreeSet<String>,
96}
97
98impl<D: Dealloc> Default for ModuleCache<D> {
99 fn default() -> Self {
100 Self {
101 complete: default(),
102 progress: default(),
103 }
104 }
105}
106
107pub enum JsonStackElement<D: Dealloc> {
108 Object(JsonStackObject<D>),
109 Array(Vec<Any<D>>),
110}
111
112pub struct JsonStackObject<D: Dealloc> {
113 pub map: BTreeMap<String, Any<D>>,
114 pub key: String,
115}
116
117pub enum JsonElement<D: Dealloc> {
118 None,
119 Stack(JsonStackElement<D>),
120 Any(Any<D>),
121}
122
123#[derive(Debug)]
124pub struct ParseResult<D: Dealloc> {
125 pub data_type: DataType,
126 pub any: Any<D>,
127}
128
129pub fn to_js_string<M: Manager>(manager: M, s: String) -> JsStringRef<M::Dealloc> {
130 new_string(manager, s.encode_utf16().collect::<Vec<_>>()).to_ref()
131}
132
133pub fn to_js_bigint<M: Manager>(manager: M, b: BigInt) -> JsBigintRef<M::Dealloc> {
134 let sign = match b.sign {
135 Sign::Positive => crate::js::js_bigint::Sign::Positive,
136 Sign::Negative => crate::js::js_bigint::Sign::Negative,
137 };
138 new_bigint(manager, sign, b.value.value).to_ref()
139}
140
141fn try_id_to_any<M: Manager>(
142 s: &str,
143 _manager: M,
144 consts: &BTreeMap<String, Any<M::Dealloc>>,
145) -> Option<Any<M::Dealloc>> {
146 match s {
147 "null" => Some(Any::move_from(Null())),
148 "true" => Some(Any::move_from(true)),
149 "false" => Some(Any::move_from(false)),
150 s if consts.contains_key(s) => Some(consts.get(s).unwrap().clone()),
151 _ => None,
152 }
153}
154
155impl<D: Dealloc> JsonToken<D> {
156 pub fn try_to_any<M: Manager<Dealloc = D>>(
157 self,
158 manager: M,
159 consts: &BTreeMap<String, Any<M::Dealloc>>,
160 ) -> Option<Any<M::Dealloc>> {
161 match self {
162 JsonToken::Number(f) => Some(Any::move_from(f)),
163 JsonToken::String(s) => Some(Any::move_from(to_js_string(manager, s))),
164 JsonToken::Id(s) => try_id_to_any(&s, manager, consts),
165 JsonToken::BigInt(b) => Some(Any::move_from(b.to_ref())),
166 _ => None,
167 }
168 }
169}