preserves 5.0.0-rc.9

Implementation of the Preserves serialization format.
Documentation
use std::io;
use std::marker::PhantomData;
use std::sync::Arc;

use crate::Error;
use crate::ExpectedKind;
use crate::IOValue;
use crate::IOValueDomainEncode;
use crate::IOValueReader;
use crate::Reader;
use crate::ReaderResult;
use crate::SyntaxError;
use crate::Writer;

pub trait Domain: std::fmt::Debug + Eq + std::hash::Hash + Ord + Clone + Sync + Send + 'static {}

pub trait DomainDecode<D: Domain> {
    fn decode_embedded<'de, R: Reader<'de> + ?Sized, VR: IOValueReader + ?Sized>(
        &mut self,
        r: &mut R,
        read_annotations: bool,
    ) -> ReaderResult<D> {
        self.decode_value(VR::read_iovalue(r, read_annotations)?)
    }

    fn decode_value(&mut self, v: IOValue) -> ReaderResult<D>;
}

pub trait DomainEncode<D: Domain> {
    fn encode_embedded(
        &mut self,
        w: &mut dyn Writer,
        d: &D,
    ) -> io::Result<()> {
        self.encode_value(d)?.write(w, &mut IOValueDomainEncode)
    }

    fn encode_value(&mut self, d: &D) -> io::Result<IOValue>;
}

impl<'a, D: Domain, T: DomainDecode<D>> DomainDecode<D> for &'a mut T {
    fn decode_embedded<'de, R: Reader<'de> + ?Sized, VR: IOValueReader + ?Sized>(
        &mut self,
        r: &mut R,
        read_annotations: bool,
    ) -> ReaderResult<D> {
        (**self).decode_embedded::<R, VR>(r, read_annotations)
    }

    fn decode_value(&mut self, v: IOValue) -> ReaderResult<D> {
        (**self).decode_value(v)
    }
}

impl<'a, D: Domain, T: DomainEncode<D>> DomainEncode<D> for &'a mut T {
    fn encode_embedded(
        &mut self,
        w: &mut dyn Writer,
        d: &D,
    ) -> io::Result<()> {
        (**self).encode_embedded(w, d)
    }

    fn encode_value(&mut self, d: &D) -> io::Result<IOValue> {
        (**self).encode_value(d)
    }
}

#[derive(Default)]
pub struct DebugDomainCodec;

impl<Err: Into<Error>, D: Domain + std::str::FromStr<Err = Err>> DomainDecode<D> for DebugDomainCodec {
    fn decode_embedded<'de, R: Reader<'de> + ?Sized, VR: IOValueReader + ?Sized>(
        &mut self,
        r: &mut R,
        _read_annotations: bool,
    ) -> ReaderResult<D> {
        r.next_str()?.parse().map_err(|e: Err| e.into())
    }

    fn decode_value(&mut self, v: IOValue) -> ReaderResult<D> {
        match v.as_string() {
            Some(s) => s.parse().map_err(|e: Err| e.into()),
            None => Err(SyntaxError::Expected(ExpectedKind::String).at(None)),
        }
    }
}

impl<D: Domain> DomainEncode<D> for DebugDomainCodec {
    fn encode_embedded(
        &mut self,
        w: &mut dyn Writer,
        d: &D,
    ) -> io::Result<()> {
        w.write_string(&format!("{:?}", d))
    }

    fn encode_value(&mut self, d: &D) -> io::Result<IOValue> {
        Ok(IOValue::new(format!("{:?}", d)))
    }
}

#[derive(Default)]
pub struct NoEmbeddedDomainCodec;

impl<D: Domain> DomainDecode<D> for NoEmbeddedDomainCodec {
    fn decode_value(&mut self, _v: IOValue) -> ReaderResult<D> {
        Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here"))?
    }
}

impl<D: Domain> DomainEncode<D> for NoEmbeddedDomainCodec {
    fn encode_value(&mut self, _d: &D) -> io::Result<IOValue> {
        Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here"))
    }
}

#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
pub enum NoEmbedded {}

impl Domain for NoEmbedded {}

pub struct ArcDomainDecode<D: Domain, Dec: DomainDecode<D> + Default>(Dec, PhantomData<D>);
pub struct ArcDomainEncode<D: Domain, Enc: DomainEncode<D> + Default>(Enc, PhantomData<D>);

impl<D: Domain> Domain for Arc<D> {}

impl<D: Domain, Dec: DomainDecode<D> + Default> DomainDecode<Arc<D>> for ArcDomainDecode<D, Dec> {
    fn decode_value(&mut self, v: IOValue) -> ReaderResult<Arc<D>> {
        Ok(Arc::new(self.0.decode_value(v)?))
    }
}

impl<D: Domain, Enc: DomainEncode<D> + Default> DomainEncode<Arc<D>> for ArcDomainEncode<D, Enc> {
    fn encode_value(&mut self, d: &Arc<D>) -> io::Result<IOValue> {
        self.0.encode_value(d.as_ref())
    }
}

impl<D: Domain, Dec: DomainDecode<D> + Default> Default for ArcDomainDecode<D, Dec> {
    fn default() -> Self {
        Self(Default::default(), Default::default())
    }
}

impl<D: Domain, Enc: DomainEncode<D> + Default> Default for ArcDomainEncode<D, Enc> {
    fn default() -> Self {
        Self(Default::default(), Default::default())
    }
}