Support deserialization into byte arrays for BLOB's via serde_bytes.
This commit is contained in:
parent
70f4c53854
commit
41dd989866
@ -20,6 +20,7 @@ Enhancements
|
||||
|
||||
* Added `into_array` and `into_typed_array` for `Dynamic`.
|
||||
* Added `FnPtr::call` and `FnPtr::call_within_context` to simplify calling a function pointer.
|
||||
* BLob's can now be deserialized (using `from_dynamic`) into `Vec<u8>` via [`serde_bytes`](https://crates.io/crates/serde_bytes).
|
||||
|
||||
Deprecated and Gated API's
|
||||
--------------------------
|
||||
|
@ -22,6 +22,9 @@ num-traits = { version = "0.2", default-features = false }
|
||||
smartstring = { version = "0.2.8", default-features = false }
|
||||
rhai_codegen = { version = "1.2", path = "codegen", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
serde_bytes = "0.11"
|
||||
|
||||
[features]
|
||||
default = ["ahash/std", "num-traits/std"]
|
||||
unchecked = [] # unchecked arithmetic
|
||||
|
@ -10,7 +10,7 @@ use std::prelude::v1::*;
|
||||
use std::{any::type_name, fmt};
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
use crate::Array;
|
||||
use crate::{Array, Blob};
|
||||
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
use crate::Map;
|
||||
@ -154,7 +154,7 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> {
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Union::Array(_, _, _) => self.deserialize_seq(visitor),
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Union::Blob(_, _, _) => self.deserialize_seq(visitor),
|
||||
Union::Blob(_, _, _) => self.deserialize_bytes(visitor),
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
Union::Map(_, _, _) => self.deserialize_map(visitor),
|
||||
Union::FnPtr(_, _, _) => self.type_error(),
|
||||
@ -357,12 +357,20 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> {
|
||||
self.deserialize_str(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_bytes<V: Visitor<'de>>(self, _: V) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
self.type_error()
|
||||
fn deserialize_bytes<V: Visitor<'de>>(
|
||||
self,
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
self.value
|
||||
.downcast_ref::<Blob>()
|
||||
.map_or_else(|| self.type_error(), |x| visitor.visit_bytes(x))
|
||||
}
|
||||
|
||||
fn deserialize_byte_buf<V: Visitor<'de>>(self, _: V) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
self.type_error()
|
||||
fn deserialize_byte_buf<V: Visitor<'de>>(
|
||||
self,
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
self.deserialize_bytes(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_option<V: Visitor<'de>>(
|
||||
@ -402,7 +410,7 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> {
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
return self.value.downcast_ref::<Array>().map_or_else(
|
||||
|| self.type_error(),
|
||||
|arr| _visitor.visit_seq(IterateArray::new(arr.iter())),
|
||||
|arr| _visitor.visit_seq(IterateDynamicArray::new(arr.iter())),
|
||||
);
|
||||
|
||||
#[cfg(feature = "no_index")]
|
||||
@ -497,20 +505,21 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> {
|
||||
}
|
||||
|
||||
/// `SeqAccess` implementation for arrays.
|
||||
struct IterateArray<'a, ITER: Iterator<Item = &'a Dynamic>> {
|
||||
struct IterateDynamicArray<'a, ITER: Iterator<Item = &'a Dynamic>> {
|
||||
/// Iterator for a stream of [`Dynamic`][crate::Dynamic] values.
|
||||
iter: ITER,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
impl<'a, ITER: Iterator<Item = &'a Dynamic>> IterateArray<'a, ITER> {
|
||||
impl<'a, ITER: Iterator<Item = &'a Dynamic>> IterateDynamicArray<'a, ITER> {
|
||||
#[must_use]
|
||||
pub fn new(iter: ITER) -> Self {
|
||||
Self { iter }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a: 'de, 'de, ITER: Iterator<Item = &'a Dynamic>> SeqAccess<'de> for IterateArray<'a, ITER> {
|
||||
impl<'a: 'de, 'de, ITER: Iterator<Item = &'a Dynamic>> SeqAccess<'de>
|
||||
for IterateDynamicArray<'a, ITER>
|
||||
{
|
||||
type Error = Box<EvalAltResult>;
|
||||
|
||||
fn next_element_seed<T: DeserializeSeed<'de>>(
|
||||
|
@ -257,11 +257,11 @@ impl Serializer for &mut DynamicSerializer {
|
||||
}
|
||||
|
||||
fn serialize_str(self, v: &str) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||
Ok(v.to_string().into())
|
||||
Ok(v.into())
|
||||
}
|
||||
|
||||
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||
Ok(Dynamic::from(v.to_vec()))
|
||||
Ok(v.into())
|
||||
}
|
||||
|
||||
fn serialize_none(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||
|
@ -2109,6 +2109,9 @@ impl Dynamic {
|
||||
v.try_cast::<T>().ok_or_else(|| typ)
|
||||
})
|
||||
.collect(),
|
||||
Union::Blob(_, _, _) if TypeId::of::<T>() == TypeId::of::<u8>() => {
|
||||
Ok(self.cast::<Vec<T>>())
|
||||
}
|
||||
#[cfg(not(feature = "no_closure"))]
|
||||
Union::Shared(cell, _, _) => {
|
||||
#[cfg(not(feature = "sync"))]
|
||||
|
@ -775,3 +775,23 @@ fn test_serde_optional() -> Result<(), Box<EvalAltResult>> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
fn test_serde_blob() -> Result<(), Box<EvalAltResult>> {
|
||||
let engine = Engine::new();
|
||||
|
||||
let r = engine.eval::<Dynamic>(
|
||||
"
|
||||
let x = blob(10);
|
||||
for i in range(0, 10) { x[i] = i; }
|
||||
x
|
||||
",
|
||||
)?;
|
||||
|
||||
let r = from_dynamic::<serde_bytes::ByteBuf>(&r)?;
|
||||
|
||||
assert_eq!(r.to_vec(), vec![0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user