1use crate::api::formatting::map_std_type_name;
4use crate::types::dynamic::Union;
5use crate::{Dynamic, ImmutableString, LexError, Position, RhaiError, RhaiResultOf, ERR};
6use serde::de::{Error, IntoDeserializer, Visitor};
7use serde::{Deserialize, Deserializer};
8#[cfg(feature = "no_std")]
9use std::prelude::v1::*;
10use std::{any::type_name, fmt};
11
12pub struct DynamicDeserializer<'de>(&'de Dynamic);
14
15impl<'de> IntoDeserializer<'de, RhaiError> for &'de Dynamic {
16 type Deserializer = DynamicDeserializer<'de>;
17
18 #[inline(always)]
19 #[must_use]
20 fn into_deserializer(self) -> Self::Deserializer {
21 DynamicDeserializer(self)
22 }
23}
24
25impl<'de> DynamicDeserializer<'de> {
26 #[inline(always)]
31 #[must_use]
32 pub const fn new(value: &'de Dynamic) -> Self {
33 Self(value)
34 }
35 #[cold]
37 #[inline(always)]
38 fn type_error<T>(&self) -> RhaiResultOf<T> {
39 self.type_error_str(map_std_type_name(type_name::<T>(), false))
40 }
41 #[cold]
43 #[inline(never)]
44 fn type_error_str<T>(&self, actual: &str) -> RhaiResultOf<T> {
45 let expected = map_std_type_name(self.0.type_name(), false).into();
46 Err(ERR::ErrorMismatchOutputType(actual.into(), expected, Position::NONE).into())
47 }
48 #[inline(always)]
49 fn deserialize_int<V: Visitor<'de>>(v: crate::INT, visitor: V) -> RhaiResultOf<V::Value> {
50 #[cfg(not(feature = "only_i32"))]
51 return visitor.visit_i64(v);
52 #[cfg(feature = "only_i32")]
53 return visitor.visit_i32(v);
54 }
55}
56
57pub fn from_dynamic<'de, T: Deserialize<'de>>(value: &'de Dynamic) -> RhaiResultOf<T> {
109 T::deserialize(DynamicDeserializer::new(value))
110}
111
112impl Error for RhaiError {
113 #[cold]
114 #[inline(never)]
115 fn custom<T: fmt::Display>(err: T) -> Self {
116 LexError::ImproperSymbol(String::new(), err.to_string())
117 .into_err(Position::NONE)
118 .into()
119 }
120}
121
122impl<'de> Deserializer<'de> for DynamicDeserializer<'de> {
123 type Error = RhaiError;
124
125 fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
126 if type_name::<V::Value>() == type_name::<Dynamic>() {
127 return Ok(reify! { self.0.clone() => !!! V::Value });
128 }
129
130 match self.0 .0 {
131 Union::Unit(..) => self.deserialize_unit(visitor),
132 Union::Bool(..) => self.deserialize_bool(visitor),
133 Union::Str(..) => self.deserialize_str(visitor),
134 Union::Char(..) => self.deserialize_char(visitor),
135
136 #[cfg(not(feature = "only_i32"))]
137 Union::Int(..) => self.deserialize_i64(visitor),
138 #[cfg(feature = "only_i32")]
139 Union::Int(..) => self.deserialize_i32(visitor),
140
141 #[cfg(not(feature = "no_float"))]
142 #[cfg(not(feature = "f32_float"))]
143 Union::Float(..) => self.deserialize_f64(visitor),
144 #[cfg(not(feature = "no_float"))]
145 #[cfg(feature = "f32_float")]
146 Union::Float(..) => self.deserialize_f32(visitor),
147
148 #[cfg(feature = "decimal")]
149 #[cfg(not(feature = "f32_float"))]
150 Union::Decimal(..) => self.deserialize_f64(visitor),
151 #[cfg(feature = "decimal")]
152 #[cfg(feature = "f32_float")]
153 Union::Decimal(..) => self.deserialize_f32(visitor),
154
155 #[cfg(not(feature = "no_index"))]
156 Union::Array(..) => self.deserialize_seq(visitor),
157 #[cfg(not(feature = "no_index"))]
158 Union::Blob(..) => self.deserialize_bytes(visitor),
159 #[cfg(not(feature = "no_object"))]
160 Union::Map(..) => self.deserialize_map(visitor),
161 Union::FnPtr(..) => self.type_error(),
162 #[cfg(not(feature = "no_time"))]
163 Union::TimeStamp(..) => self.type_error(),
164
165 Union::Variant(ref value, ..) if value.is::<i8>() => self.deserialize_i8(visitor),
166 Union::Variant(ref value, ..) if value.is::<i16>() => self.deserialize_i16(visitor),
167 Union::Variant(ref value, ..) if value.is::<i32>() => self.deserialize_i32(visitor),
168 Union::Variant(ref value, ..) if value.is::<i64>() => self.deserialize_i64(visitor),
169 Union::Variant(ref value, ..) if value.is::<i128>() => self.deserialize_i128(visitor),
170 Union::Variant(ref value, ..) if value.is::<u8>() => self.deserialize_u8(visitor),
171 Union::Variant(ref value, ..) if value.is::<u16>() => self.deserialize_u16(visitor),
172 Union::Variant(ref value, ..) if value.is::<u32>() => self.deserialize_u32(visitor),
173 Union::Variant(ref value, ..) if value.is::<u64>() => self.deserialize_u64(visitor),
174 Union::Variant(ref value, ..) if value.is::<u128>() => self.deserialize_u128(visitor),
175
176 Union::Variant(..) => self.type_error(),
177
178 #[cfg(not(feature = "no_closure"))]
179 Union::Shared(..) => self.type_error(),
180 }
181 }
182
183 fn deserialize_bool<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
184 visitor.visit_bool(self.0.as_bool().or_else(|_| self.type_error())?)
185 }
186
187 fn deserialize_i8<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
188 match self.0.as_int() {
189 Ok(v) => Self::deserialize_int(v, visitor),
190 Err(_) => self
191 .0
192 .downcast_ref::<i8>()
193 .map_or_else(|| self.type_error(), |&x| visitor.visit_i8(x)),
194 }
195 }
196
197 fn deserialize_i16<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
198 match self.0.as_int() {
199 Ok(v) => Self::deserialize_int(v, visitor),
200 Err(_) => self
201 .0
202 .downcast_ref::<i16>()
203 .map_or_else(|| self.type_error(), |&x| visitor.visit_i16(x)),
204 }
205 }
206
207 fn deserialize_i32<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
208 match self.0.as_int() {
209 Ok(v) => Self::deserialize_int(v, visitor),
210 _ if cfg!(feature = "only_i32") => self.type_error(),
211 _ => self
212 .0
213 .downcast_ref::<i32>()
214 .map_or_else(|| self.type_error(), |&x| visitor.visit_i32(x)),
215 }
216 }
217
218 fn deserialize_i64<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
219 match self.0.as_int() {
220 Ok(v) => Self::deserialize_int(v, visitor),
221 _ if cfg!(not(feature = "only_i32")) => self.type_error(),
222 _ => self
223 .0
224 .downcast_ref::<i64>()
225 .map_or_else(|| self.type_error(), |&x| visitor.visit_i64(x)),
226 }
227 }
228
229 fn deserialize_i128<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
230 match self.0.as_int() {
231 Ok(v) => Self::deserialize_int(v, visitor),
232 _ if cfg!(not(feature = "only_i32")) => self.type_error(),
233 _ => self
234 .0
235 .downcast_ref::<i128>()
236 .map_or_else(|| self.type_error(), |&x| visitor.visit_i128(x)),
237 }
238 }
239
240 fn deserialize_u8<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
241 match self.0.as_int() {
242 Ok(v) => Self::deserialize_int(v, visitor),
243 Err(_) => self
244 .0
245 .downcast_ref::<u8>()
246 .map_or_else(|| self.type_error(), |&x| visitor.visit_u8(x)),
247 }
248 }
249
250 fn deserialize_u16<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
251 match self.0.as_int() {
252 Ok(v) => Self::deserialize_int(v, visitor),
253 Err(_) => self
254 .0
255 .downcast_ref::<u16>()
256 .map_or_else(|| self.type_error(), |&x| visitor.visit_u16(x)),
257 }
258 }
259
260 fn deserialize_u32<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
261 match self.0.as_int() {
262 Ok(v) => Self::deserialize_int(v, visitor),
263 Err(_) => self
264 .0
265 .downcast_ref::<u32>()
266 .map_or_else(|| self.type_error(), |&x| visitor.visit_u32(x)),
267 }
268 }
269
270 fn deserialize_u64<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
271 match self.0.as_int() {
272 Ok(v) => Self::deserialize_int(v, visitor),
273 Err(_) => self
274 .0
275 .downcast_ref::<u64>()
276 .map_or_else(|| self.type_error(), |&x| visitor.visit_u64(x)),
277 }
278 }
279
280 fn deserialize_u128<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
281 match self.0.as_int() {
282 Ok(v) => Self::deserialize_int(v, visitor),
283 Err(_) => self
284 .0
285 .downcast_ref::<u128>()
286 .map_or_else(|| self.type_error(), |&x| visitor.visit_u128(x)),
287 }
288 }
289
290 fn deserialize_f32<V: Visitor<'de>>(self, _visitor: V) -> RhaiResultOf<V::Value> {
291 #[cfg(not(feature = "no_float"))]
292 return self
293 .0
294 .downcast_ref::<f32>()
295 .map_or_else(|| self.type_error(), |&x| _visitor.visit_f32(x));
296
297 #[allow(unreachable_code)]
298 {
299 #[cfg(feature = "decimal")]
300 {
301 use rust_decimal::prelude::ToPrimitive;
302
303 return self
304 .0
305 .downcast_ref::<rust_decimal::Decimal>()
306 .and_then(|&x| x.to_f32())
307 .map_or_else(|| self.type_error(), |v| _visitor.visit_f32(v));
308 }
309
310 self.type_error_str("f32")
311 }
312 }
313
314 fn deserialize_f64<V: Visitor<'de>>(self, _visitor: V) -> RhaiResultOf<V::Value> {
315 #[cfg(not(feature = "no_float"))]
316 return self
317 .0
318 .downcast_ref::<f64>()
319 .map_or_else(|| self.type_error(), |&x| _visitor.visit_f64(x));
320
321 #[allow(unreachable_code)]
322 {
323 #[cfg(feature = "decimal")]
324 {
325 use rust_decimal::prelude::ToPrimitive;
326
327 return self
328 .0
329 .downcast_ref::<rust_decimal::Decimal>()
330 .and_then(|&x| x.to_f64())
331 .map_or_else(|| self.type_error(), |v| _visitor.visit_f64(v));
332 }
333
334 self.type_error_str("f64")
335 }
336 }
337
338 fn deserialize_char<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
339 self.0
340 .downcast_ref::<char>()
341 .map_or_else(|| self.type_error(), |&x| visitor.visit_char(x))
342 }
343
344 fn deserialize_str<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
345 self.0
346 .downcast_ref::<ImmutableString>()
347 .map_or_else(|| self.type_error(), |x| visitor.visit_borrowed_str(x))
348 }
349
350 fn deserialize_string<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
351 self.deserialize_str(visitor)
352 }
353
354 fn deserialize_bytes<V: Visitor<'de>>(self, _visitor: V) -> RhaiResultOf<V::Value> {
355 #[cfg(not(feature = "no_index"))]
356 return self
357 .0
358 .downcast_ref::<crate::Blob>()
359 .map_or_else(|| self.type_error(), |x| _visitor.visit_bytes(x));
360
361 #[cfg(feature = "no_index")]
362 return self.type_error();
363 }
364
365 fn deserialize_byte_buf<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
366 self.deserialize_bytes(visitor)
367 }
368
369 fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
370 if self.0.is_unit() {
371 visitor.visit_none()
372 } else {
373 visitor.visit_some(self)
374 }
375 }
376
377 fn deserialize_unit<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
378 self.0
379 .downcast_ref::<()>()
380 .map_or_else(|| self.type_error(), |()| visitor.visit_unit())
381 }
382
383 fn deserialize_unit_struct<V: Visitor<'de>>(
384 self,
385 _name: &'static str,
386 visitor: V,
387 ) -> RhaiResultOf<V::Value> {
388 self.deserialize_unit(visitor)
389 }
390
391 fn deserialize_newtype_struct<V: Visitor<'de>>(
392 self,
393 _name: &'static str,
394 visitor: V,
395 ) -> RhaiResultOf<V::Value> {
396 visitor.visit_newtype_struct(self)
397 }
398
399 fn deserialize_seq<V: Visitor<'de>>(self, _visitor: V) -> RhaiResultOf<V::Value> {
400 #[cfg(not(feature = "no_index"))]
401 return self.0.downcast_ref::<crate::Array>().map_or_else(
402 || self.type_error(),
403 |arr| _visitor.visit_seq(IterateDynamicArray::new(arr.iter())),
404 );
405
406 #[cfg(feature = "no_index")]
407 return self.type_error();
408 }
409
410 fn deserialize_tuple<V: Visitor<'de>>(self, _len: usize, visitor: V) -> RhaiResultOf<V::Value> {
411 self.deserialize_seq(visitor)
412 }
413
414 fn deserialize_tuple_struct<V: Visitor<'de>>(
415 self,
416 _name: &'static str,
417 _len: usize,
418 visitor: V,
419 ) -> RhaiResultOf<V::Value> {
420 self.deserialize_seq(visitor)
421 }
422
423 fn deserialize_map<V: Visitor<'de>>(self, _visitor: V) -> RhaiResultOf<V::Value> {
424 #[cfg(not(feature = "no_object"))]
425 return self.0.downcast_ref::<crate::Map>().map_or_else(
426 || self.type_error(),
427 |map| {
428 _visitor.visit_map(IterateMap::new(
429 map.keys().map(crate::SmartString::as_str),
430 map.values(),
431 ))
432 },
433 );
434
435 #[cfg(feature = "no_object")]
436 return self.type_error();
437 }
438
439 fn deserialize_struct<V: Visitor<'de>>(
440 self,
441 _name: &'static str,
442 _fields: &'static [&'static str],
443 _visitor: V,
444 ) -> RhaiResultOf<V::Value> {
445 #[cfg(not(feature = "no_object"))]
446 return self.0.downcast_ref::<crate::Map>().map_or_else(
447 || {
448 Err(ERR::ErrorMismatchOutputType(
449 map_std_type_name(type_name::<crate::Map>(), false).into(),
450 map_std_type_name(self.0.type_name(), false).into(),
451 Position::NONE,
452 )
453 .into())
454 },
455 |map| {
456 _visitor.visit_map(IterateMap::new(
457 map.keys().map(crate::SmartString::as_str),
458 map.values(),
459 ))
460 },
461 );
462
463 #[cfg(feature = "no_object")]
464 return self.type_error();
465 }
466
467 fn deserialize_enum<V: Visitor<'de>>(
468 self,
469 _name: &'static str,
470 _variants: &'static [&'static str],
471 visitor: V,
472 ) -> RhaiResultOf<V::Value> {
473 match self.0.read_lock::<ImmutableString>() {
474 Some(s) => visitor.visit_enum(s.into_deserializer()),
475 None => {
476 #[cfg(not(feature = "no_object"))]
477 return self.0.downcast_ref::<crate::Map>().map_or_else(
478 || self.type_error(),
479 |map| {
480 let mut iter = map.iter();
481 let first = iter.next();
482 let second = iter.next();
483 match (first, second) {
484 (Some((key, value)), None) => visitor.visit_enum(EnumDeserializer {
485 tag: key,
486 content: DynamicDeserializer::new(value),
487 }),
488 _ => self.type_error(),
489 }
490 },
491 );
492 #[cfg(feature = "no_object")]
493 return self.type_error();
494 }
495 }
496 }
497
498 #[inline(always)]
499 fn deserialize_identifier<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
500 self.deserialize_str(visitor)
501 }
502
503 #[inline(always)]
504 fn deserialize_ignored_any<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
505 self.deserialize_any(visitor)
506 }
507}
508
509#[cfg(not(feature = "no_index"))]
511struct IterateDynamicArray<'de, ITER: Iterator<Item = &'de Dynamic>> {
512 iter: ITER,
514}
515
516#[cfg(not(feature = "no_index"))]
517impl<'de, ITER: Iterator<Item = &'de Dynamic>> IterateDynamicArray<'de, ITER> {
518 #[inline(always)]
519 #[must_use]
520 pub const fn new(iter: ITER) -> Self {
521 Self { iter }
522 }
523}
524
525#[cfg(not(feature = "no_index"))]
526impl<'de, ITER: Iterator<Item = &'de Dynamic>> serde::de::SeqAccess<'de>
527 for IterateDynamicArray<'de, ITER>
528{
529 type Error = RhaiError;
530
531 fn next_element_seed<T: serde::de::DeserializeSeed<'de>>(
532 &mut self,
533 seed: T,
534 ) -> RhaiResultOf<Option<T::Value>> {
535 self.iter.next().map_or(Ok(None), |item| {
537 seed.deserialize(item.into_deserializer()).map(Some)
538 })
539 }
540}
541
542#[cfg(not(feature = "no_object"))]
544struct IterateMap<'de, K: Iterator<Item = &'de str>, V: Iterator<Item = &'de Dynamic>> {
545 keys: K,
547 values: V,
549}
550
551#[cfg(not(feature = "no_object"))]
552impl<'de, K: Iterator<Item = &'de str>, V: Iterator<Item = &'de Dynamic>> IterateMap<'de, K, V> {
553 #[inline(always)]
554 #[must_use]
555 pub const fn new(keys: K, values: V) -> Self {
556 Self { keys, values }
557 }
558}
559
560#[cfg(not(feature = "no_object"))]
561impl<'de, K: Iterator<Item = &'de str>, V: Iterator<Item = &'de Dynamic>> serde::de::MapAccess<'de>
562 for IterateMap<'de, K, V>
563{
564 type Error = RhaiError;
565
566 fn next_key_seed<S: serde::de::DeserializeSeed<'de>>(
567 &mut self,
568 seed: S,
569 ) -> RhaiResultOf<Option<S::Value>> {
570 self.keys
572 .next()
573 .map(<_>::into_deserializer)
574 .map_or(Ok(None), |d| seed.deserialize(d).map(Some))
575 }
576
577 fn next_value_seed<S: serde::de::DeserializeSeed<'de>>(
578 &mut self,
579 seed: S,
580 ) -> RhaiResultOf<S::Value> {
581 seed.deserialize(self.values.next().unwrap().into_deserializer())
583 }
584}
585
586#[cfg(not(feature = "no_object"))]
587struct EnumDeserializer<'de> {
588 tag: &'de str,
589 content: DynamicDeserializer<'de>,
590}
591
592#[cfg(not(feature = "no_object"))]
593impl<'de> serde::de::EnumAccess<'de> for EnumDeserializer<'de> {
594 type Error = RhaiError;
595 type Variant = Self;
596
597 fn variant_seed<V: serde::de::DeserializeSeed<'de>>(
598 self,
599 seed: V,
600 ) -> RhaiResultOf<(V::Value, Self::Variant)> {
601 seed.deserialize(self.tag.into_deserializer())
602 .map(|v| (v, self))
603 }
604}
605
606#[cfg(not(feature = "no_object"))]
607impl<'de> serde::de::VariantAccess<'de> for EnumDeserializer<'de> {
608 type Error = RhaiError;
609
610 #[inline(always)]
611 fn unit_variant(self) -> RhaiResultOf<()> {
612 Deserialize::deserialize(self.content)
613 }
614
615 #[inline(always)]
616 fn newtype_variant_seed<T: serde::de::DeserializeSeed<'de>>(
617 self,
618 seed: T,
619 ) -> RhaiResultOf<T::Value> {
620 seed.deserialize(self.content)
621 }
622
623 #[inline(always)]
624 fn tuple_variant<V: Visitor<'de>>(self, len: usize, visitor: V) -> RhaiResultOf<V::Value> {
625 self.content.deserialize_tuple(len, visitor)
626 }
627
628 #[inline(always)]
629 fn struct_variant<V: Visitor<'de>>(
630 self,
631 fields: &'static [&'static str],
632 visitor: V,
633 ) -> RhaiResultOf<V::Value> {
634 self.content.deserialize_struct("", fields, visitor)
635 }
636}