Add support for deserialization of custom type/shared value from into another Dynamic.

This commit is contained in:
Stephen Chung
2023-04-28 23:16:00 +08:00
parent 72cfd42ab7
commit ae59a3321b
6 changed files with 65 additions and 19 deletions

View File

@@ -4,8 +4,9 @@ use rhai::{
serde::{from_dynamic, to_dynamic},
Dynamic, Engine, EvalAltResult, ImmutableString, Scope, INT,
};
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::json;
use std::sync::Arc;
#[cfg(not(feature = "no_index"))]
use rhai::Array;
@@ -383,6 +384,37 @@ fn test_serde_de_primary_types() -> Result<(), Box<EvalAltResult>> {
Ok(())
}
#[cfg(not(feature = "no_object"))]
#[test]
fn test_serde_de_variants() -> Result<(), Box<EvalAltResult>> {
#[derive(Debug)]
struct Foo;
#[derive(Debug, Deserialize)]
struct Bar {
#[serde(deserialize_with = "deserialize_foo")]
value: Arc<Foo>,
}
fn deserialize_foo<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Arc<Foo>, D::Error> {
let value = <Dynamic as Deserialize>::deserialize(deserializer)?;
value
.try_cast::<Arc<Foo>>()
.ok_or_else(|| serde::de::Error::custom("type error"))
}
let value = Arc::new(Foo);
let mut map = Map::new();
map.insert("value".into(), Dynamic::from(value.clone()));
let x = Dynamic::from(map);
let bar = from_dynamic::<Bar>(&x)?;
assert!(Arc::ptr_eq(&bar.value, &value));
Ok(())
}
#[test]
fn test_serde_de_integer_types() -> Result<(), Box<EvalAltResult>> {
assert_eq!(42, from_dynamic::<i8>(&Dynamic::from(42 as INT))?);