1use std::mem::transmute;
2
3use libquickjs_ng_sys::JSContext;
4use serde::de::{
5 self, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess,
6 Visitor,
7};
8use serde::{forward_to_deserialize_any, Deserialize};
9
10use crate::utils::deserialize_borrowed_str;
11use crate::value::{JsTag, OwnedJsArray, OwnedJsObject, OwnedJsPropertyIterator, OwnedJsValue};
12
13use super::error::{Error, Result};
14
15pub struct Deserializer<'de> {
17 context: *mut JSContext,
18 root: &'de OwnedJsValue,
19 paths: Vec<(OwnedJsValue, u32, Option<OwnedJsPropertyIterator>)>,
20 current: Option<OwnedJsValue>,
21}
22
23impl<'de> Deserializer<'de> {
24 fn from_js(context: *mut JSContext, root: &'de OwnedJsValue) -> Self {
25 Deserializer {
26 context,
27 root,
28 paths: Vec::new(),
29 current: Some(root.clone()),
30 }
31 }
32}
33
34pub fn from_js<'a, T>(context: *mut JSContext, value: &'a OwnedJsValue) -> Result<T>
36where
37 T: Deserialize<'a>,
38{
39 let mut deserializer = Deserializer::from_js(context, value);
40 let t = T::deserialize(&mut deserializer)?;
41 Ok(t)
42}
43
44impl<'de> Deserializer<'de> {
45 fn get_current(&self) -> &OwnedJsValue {
46 if let Some(current) = self.current.as_ref() {
47 current
48 } else {
49 self.root
50 }
51 }
52
53 fn next(&mut self) -> Result<Option<()>> {
54 let (current, index, obj_iter) = self.paths.last_mut().expect("current must be Some");
55
56 let next = if current.is_array() {
57 let current = OwnedJsArray::try_from_value(current.clone()).unwrap();
58 let item = current.get_index(*index)?;
59 if item.is_some() {
60 self.current = item;
61 *index += 1;
62 Some(())
63 } else {
64 None
65 }
66 } else if current.is_object() {
67 let obj_iter = obj_iter.as_mut().expect("obj_iter must be Some");
68 if let Some(ret) = obj_iter.next() {
69 self.current = Some(ret?);
70 *index += 1;
72 Some(())
73 } else {
74 None
75 }
76 } else {
77 return Err(Error::ExpectedArrayOrObject);
78 };
79
80 if next.is_some() {
81 Ok(next)
82 } else {
83 Ok(None)
84 }
85 }
86
87 fn guard_circular_reference(&self, current: &OwnedJsValue) -> Result<()> {
88 if self.paths.iter().any(|(p, _, _)| p == current) {
89 Err(Error::CircularReference)
90 } else {
91 Ok(())
92 }
93 }
94
95 fn enter_array(&mut self) -> Result<()> {
96 let mut current = self.get_current().clone();
97
98 if current.is_proxy() {
99 current = current.get_proxy_target(true)?;
100 }
101
102 if current.is_array() {
103 self.guard_circular_reference(¤t)?;
104 self.paths.push((current, 0, None));
105 Ok(())
106 } else {
107 Err(Error::ExpectedArray)
108 }
109 }
110
111 fn enter_object(&mut self) -> Result<()> {
112 let mut current = self.get_current().clone();
113
114 if current.is_proxy() {
115 current = current.get_proxy_target(true)?;
116 }
117
118 if current.is_object() {
119 let obj = OwnedJsObject::try_from_value(current.clone()).unwrap();
120 self.guard_circular_reference(¤t)?;
121 self.paths.push((current, 0, Some(obj.properties_iter()?)));
122 Ok(())
123 } else {
124 Err(Error::ExpectedObject)
125 }
126 }
127
128 fn leave(&mut self) {
129 if let Some((current, _, _)) = self.paths.pop() {
130 self.current = Some(current);
131 }
132 }
133
134 fn parse_string(&mut self) -> Result<String> {
135 let current = self.get_current();
136 if current.is_string() {
137 current.to_string().map_err(|err| err.into())
138 } else {
139 Err(Error::ExpectedString)
140 }
141 }
142
143 fn parse_borrowed_str(&mut self) -> Result<&'de str> {
144 let current = self.get_current();
145 if current.is_string() {
146 let s = deserialize_borrowed_str(self.context, ¤t.value).unwrap();
147
148 let s = unsafe { transmute(s) };
151
152 Ok(s)
153 } else {
154 Err(Error::ExpectedString)
155 }
156 }
157}
158
159impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
160 type Error = Error;
161
162 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
166 where
167 V: Visitor<'de>,
168 {
169 let current = self.get_current();
170
171 match current.tag() {
172 JsTag::Undefined => visitor.visit_unit(),
173 JsTag::Int => visitor.visit_i32(current.to_int()?),
174 JsTag::Bool => visitor.visit_bool(current.to_bool()?),
175 JsTag::Null => visitor.visit_unit(),
176 JsTag::String => visitor.visit_string(current.to_string()?),
177 JsTag::Float64 => visitor.visit_f64(current.to_float()?),
178 JsTag::Object => {
179 if current.is_array() {
180 self.deserialize_seq(visitor)
181 } else {
182 self.deserialize_map(visitor)
183 }
184 }
185 JsTag::Symbol => visitor.visit_unit(),
186 JsTag::Module => visitor.visit_unit(),
187 JsTag::Exception => self.deserialize_map(visitor),
188 JsTag::CatchOffset => visitor.visit_unit(),
189 JsTag::Uninitialized => visitor.visit_unit(),
190 JsTag::FunctionBytecode => visitor.visit_unit(),
191 #[cfg(feature = "bigint")]
192 JsTag::ShortBigInt => {
193 let bigint = current.to_bigint()?;
194 visitor.visit_i64(bigint.as_i64().ok_or(Error::BigIntOverflow)?)
195 }
196 #[cfg(feature = "bigint")]
197 JsTag::BigInt => {
198 let bigint = current.to_bigint()?;
199 visitor.visit_i64(bigint.as_i64().ok_or(Error::BigIntOverflow)?)
200 } }
209 }
210
211 forward_to_deserialize_any! {
212 bool
213 i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64
214 string char
215 unit
216 identifier ignored_any
217 }
218
219 fn deserialize_str<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
220 where
221 V: Visitor<'de>,
222 {
223 visitor.visit_borrowed_str(self.parse_borrowed_str()?)
224 }
225
226 fn deserialize_seq<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
227 where
228 V: Visitor<'de>,
229 {
230 self.enter_array()?;
231 let r = visitor.visit_seq(&mut *self);
232 self.leave();
233 r
234 }
235
236 fn deserialize_bytes<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
237 where
238 V: Visitor<'de>,
239 {
240 self.deserialize_byte_buf(visitor)
241 }
242
243 fn deserialize_byte_buf<V>(self, _: V) -> std::result::Result<V::Value, Self::Error>
245 where
246 V: Visitor<'de>,
247 {
248 unimplemented!("borrowed bytes not supported yet")
249 }
251
252 fn deserialize_tuple<V>(
253 self,
254 _len: usize,
255 visitor: V,
256 ) -> std::result::Result<V::Value, Self::Error>
257 where
258 V: Visitor<'de>,
259 {
260 self.deserialize_seq(visitor)
261 }
262
263 fn deserialize_tuple_struct<V>(
264 self,
265 _name: &'static str,
266 _len: usize,
267 visitor: V,
268 ) -> std::result::Result<V::Value, Self::Error>
269 where
270 V: Visitor<'de>,
271 {
272 self.deserialize_seq(visitor)
273 }
274
275 fn deserialize_option<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
276 where
277 V: Visitor<'de>,
278 {
279 if self.get_current().is_null() || self.get_current().is_undefined() {
280 visitor.visit_none()
281 } else {
282 visitor.visit_some(self)
283 }
284 }
285
286 fn deserialize_newtype_struct<V>(
287 self,
288 _name: &'static str,
289 visitor: V,
290 ) -> std::result::Result<V::Value, Self::Error>
291 where
292 V: Visitor<'de>,
293 {
294 visitor.visit_newtype_struct(self)
295 }
296
297 fn deserialize_map<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
298 where
299 V: Visitor<'de>,
300 {
301 self.enter_object()?;
302 let r = visitor.visit_map(&mut *self);
303 self.leave();
304 r
305 }
306
307 fn deserialize_struct<V>(
314 self,
315 _name: &'static str,
316 _fields: &'static [&'static str],
317 visitor: V,
318 ) -> std::result::Result<V::Value, Self::Error>
319 where
320 V: Visitor<'de>,
321 {
322 self.deserialize_map(visitor)
323 }
324
325 fn deserialize_enum<V>(
326 self,
327 _name: &'static str,
328 _variants: &'static [&'static str],
329 visitor: V,
330 ) -> std::result::Result<V::Value, Self::Error>
331 where
332 V: Visitor<'de>,
333 {
334 if self.get_current().is_object() {
335 self.enter_object()?;
337 self.next()?;
338 let r = visitor.visit_enum(Enum::new(self));
339 self.leave();
340 r
341 } else {
342 visitor.visit_enum(self.parse_string()?.into_deserializer())
344 }
345 }
346
347 fn deserialize_unit_struct<V>(
348 self,
349 _name: &'static str,
350 visitor: V,
351 ) -> std::result::Result<V::Value, Self::Error>
352 where
353 V: Visitor<'de>,
354 {
355 self.deserialize_unit(visitor)
356 }
357}
358
359impl<'de, 'a> SeqAccess<'de> for Deserializer<'de> {
360 type Error = Error;
361
362 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
363 where
364 T: DeserializeSeed<'de>,
365 {
366 if let Some(_) = self.next()? {
367 seed.deserialize(self).map(Some)
368 } else {
369 Ok(None)
370 }
371 }
372}
373
374impl<'de, 'a> MapAccess<'de> for Deserializer<'de> {
375 type Error = Error;
376
377 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
378 where
379 K: DeserializeSeed<'de>,
380 {
381 if let Some(_) = self.next()? {
382 seed.deserialize(self).map(Some)
383 } else {
384 Ok(None)
385 }
386 }
387
388 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
389 where
390 V: DeserializeSeed<'de>,
391 {
392 self.next()?;
400 seed.deserialize(self)
401 }
402}
403
404struct Enum<'a, 'de: 'a> {
405 de: &'a mut Deserializer<'de>,
406}
407
408impl<'a, 'de> Enum<'a, 'de> {
409 fn new(de: &'a mut Deserializer<'de>) -> Self {
410 Enum { de }
411 }
412}
413
414impl<'de, 'a> EnumAccess<'de> for Enum<'a, 'de> {
420 type Error = Error;
421 type Variant = Self;
422
423 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
424 where
425 V: DeserializeSeed<'de>,
426 {
427 let val = seed.deserialize(&mut *self.de)?;
432 self.de.next()?;
433 Ok((val, self))
436 }
440}
441
442impl<'de, 'a> VariantAccess<'de> for Enum<'a, 'de> {
445 type Error = Error;
446
447 fn unit_variant(self) -> Result<()> {
450 Err(Error::ExpectedString)
451 }
452
453 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
456 where
457 T: DeserializeSeed<'de>,
458 {
459 seed.deserialize(self.de)
460 }
461
462 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
465 where
466 V: Visitor<'de>,
467 {
468 de::Deserializer::deserialize_seq(self.de, visitor)
469 }
470
471 fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
474 where
475 V: Visitor<'de>,
476 {
477 de::Deserializer::deserialize_map(self.de, visitor)
478 }
479}