use serde::{Deserialize, Serialize};
use std::marker::PhantomData;
mod collections;
pub use collections::{List, Map, Set};
pub trait State: Serialize + for<'de> Deserialize<'de> {
type Target: Serialize + for<'de> Deserialize<'de>;
fn is_halted(&self) -> bool {
false
}
fn as_internal<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
Serialize::serialize(self, serializer)
}
}
#[doc(hidden)]
pub struct AsInternal<'a, T: State>(pub &'a T);
impl<'a, T: State> Serialize for AsInternal<'a, T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.0.as_internal(serializer)
}
}
struct StateDeserializer<T>(pub PhantomData<T>);
impl<'de, T: serde::Deserialize<'de>> serde::de::DeserializeSeed<'de> for StateDeserializer<T> {
type Value = T;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
T::deserialize(deserializer)
}
}
macro_rules! impl_state_for_primitive {
($($t:ty),*) => {
$(
impl State for $t {
type Target = Self;
}
)*
};
}
impl_state_for_primitive!(
bool, i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64, char, String
);
impl<T: State> State for Option<T> {
type Target = Option<T::Target>;
fn as_internal<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
Some(value) => serializer.serialize_some(&AsInternal(value)),
None => serializer.serialize_none(),
}
}
}
impl<T: State> State for Box<T> {
type Target = Box<T::Target>;
fn as_internal<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
AsInternal(self.as_ref()).serialize(serializer)
}
}