Make Scope serializable.

This commit is contained in:
Stephen Chung
2022-09-26 18:14:45 +08:00
parent 335d12e182
commit 8d1310c0f3
6 changed files with 208 additions and 62 deletions

View File

@@ -1,14 +1,17 @@
//! Implementations of [`serde::Deserialize`].
use crate::{Dynamic, ImmutableString, INT};
use serde::de::{Deserialize, Deserializer, Error, Visitor};
use crate::{Dynamic, Identifier, ImmutableString, Scope, INT};
use serde::{
de::{Error, SeqAccess, Visitor},
Deserialize, Deserializer,
};
use std::fmt;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
struct DynamicVisitor;
impl<'d> Visitor<'d> for DynamicVisitor {
impl<'de> Visitor<'de> for DynamicVisitor {
type Value = Dynamic;
#[cold]
@@ -145,12 +148,12 @@ impl<'d> Visitor<'d> for DynamicVisitor {
}
#[inline(always)]
fn visit_newtype_struct<D: Deserializer<'d>>(self, de: D) -> Result<Self::Value, D::Error> {
fn visit_newtype_struct<D: Deserializer<'de>>(self, de: D) -> Result<Self::Value, D::Error> {
Deserialize::deserialize(de)
}
#[cfg(not(feature = "no_index"))]
fn visit_seq<A: serde::de::SeqAccess<'d>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
fn visit_seq<A: serde::de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let mut arr = crate::Array::new();
while let Some(v) = seq.next_element()? {
@@ -161,7 +164,7 @@ impl<'d> Visitor<'d> for DynamicVisitor {
}
#[cfg(not(feature = "no_object"))]
fn visit_map<M: serde::de::MapAccess<'d>>(self, mut map: M) -> Result<Self::Value, M::Error> {
fn visit_map<M: serde::de::MapAccess<'de>>(self, mut map: M) -> Result<Self::Value, M::Error> {
let mut m = crate::Map::new();
while let Some((k, v)) = map.next_entry()? {
@@ -172,17 +175,69 @@ impl<'d> Visitor<'d> for DynamicVisitor {
}
}
impl<'d> Deserialize<'d> for Dynamic {
impl<'de> Deserialize<'de> for Dynamic {
#[inline(always)]
fn deserialize<D: Deserializer<'d>>(de: D) -> Result<Self, D::Error> {
de.deserialize_any(DynamicVisitor)
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_any(DynamicVisitor)
}
}
impl<'d> Deserialize<'d> for ImmutableString {
#[inline]
fn deserialize<D: Deserializer<'d>>(de: D) -> Result<Self, D::Error> {
let s: String = Deserialize::deserialize(de)?;
impl<'de> Deserialize<'de> for ImmutableString {
#[inline(always)]
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let s: String = Deserialize::deserialize(deserializer)?;
Ok(s.into())
}
}
impl<'de> Deserialize<'de> for Scope<'de> {
#[inline(always)]
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Debug, Clone, Hash, Deserialize)]
struct ScopeEntry {
pub name: Identifier,
pub value: Dynamic,
#[serde(default)]
pub is_constant: bool,
}
struct VecVisitor;
impl<'de> Visitor<'de> for VecVisitor {
type Value = Scope<'static>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence")
}
#[inline]
fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut scope = if let Some(size) = access.size_hint() {
Scope::with_capacity(size)
} else {
Scope::new()
};
while let Some(ScopeEntry {
name,
value,
is_constant,
}) = access.next_element()?
{
if is_constant {
scope.push_constant_dynamic(name, value);
} else {
scope.push_dynamic(name, value);
}
}
Ok(scope)
}
}
deserializer.deserialize_seq(VecVisitor)
}
}