use crate::recursive::types::{Node, Primitive};
use std::collections::HashMap;
pub trait Diffable {
type P: Primitive;
fn to_node(&self) -> Node<Self::P>;
fn from_node(node: Node<Self::P>) -> Self;
}
impl<T: Diffable> Diffable for Vec<T> {
type P = T::P;
fn to_node(&self) -> Node<T::P> {
Node::Sequence(self.iter().map(Diffable::to_node).collect())
}
fn from_node(node: Node<Self::P>) -> Self {
match node {
Node::Sequence(v) => v.into_iter().map(T::from_node).collect(),
_ => unreachable!(),
}
}
}
impl<T: Diffable> Diffable for HashMap<String, T> {
type P = T::P;
fn to_node(&self) -> Node<T::P> {
Node::Map(self.iter().map(|(k, v)| (k.clone(), v.to_node())).collect())
}
fn from_node(node: Node<Self::P>) -> Self {
match node {
Node::Map(v) => v.into_iter().map(|(k, v)| (k, T::from_node(v))).collect(),
_ => unreachable!(),
}
}
}
macro_rules! impl_diffable_leaf {
($($t:ty),*) => {
$(
impl Primitive for $t {}
impl Diffable for $t {
type P = $t;
fn to_node(&self) -> Node<Self::P> {
Node::Leaf(self.clone())
}
fn from_node(node : Node<Self::P>) -> Self {
match node {
Node::Leaf(v) => v,
_ => unreachable!()
}
}
}
)*
};
}
impl_diffable_leaf!(
i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, bool, String, char
);