use std::io; use super::IOValue; use super::Reader; use super::Writer; use super::Value; pub trait Domain: std::fmt::Debug + Eq + std::hash::Hash + Ord + Clone { type Decode: DomainDecode + Default; type Encode: DomainEncode + Default; } pub trait DomainDecode { fn decode_embedded<'de, R: Reader<'de> + ?Sized>( &mut self, r: &mut R, read_annotations: bool, ) -> io::Result; } pub trait DomainEncode { fn encode_embedded( &mut self, w: &mut dyn Writer, d: &D, ) -> io::Result<()>; } impl<'a, D: Domain, T: DomainDecode> DomainDecode for &'a mut T { fn decode_embedded<'de, R: Reader<'de> + ?Sized>( &mut self, r: &mut R, read_annotations: bool, ) -> io::Result { (**self).decode_embedded(r, read_annotations) } } impl<'a, D: Domain, T: DomainEncode> DomainEncode for &'a mut T { fn encode_embedded( &mut self, w: &mut dyn Writer, d: &D, ) -> io::Result<()> { (**self).encode_embedded(w, d) } } #[derive(Default)] pub struct DefaultDomainCodec; impl DomainDecode for DefaultDomainCodec { fn decode_embedded<'de, R: Reader<'de> + ?Sized>( &mut self, r: &mut R, read_annotations: bool, ) -> io::Result { D::Decode::default().decode_embedded(r, read_annotations) } } impl DomainEncode for DefaultDomainCodec { fn encode_embedded( &mut self, w: &mut dyn Writer, d: &D, ) -> io::Result<()> { D::Encode::default().encode_embedded(w, d) } } #[derive(Default)] pub struct DebugDomainCodec; impl, D: Domain + std::str::FromStr> DomainDecode for DebugDomainCodec { fn decode_embedded<'de, R: Reader<'de> + ?Sized>( &mut self, r: &mut R, _read_annotations: bool, ) -> io::Result { r.next_str()?.parse().map_err(|e: Err| e.into()) } } impl DomainEncode for DebugDomainCodec { fn encode_embedded( &mut self, w: &mut dyn Writer, d: &D, ) -> io::Result<()> { w.write_string(&format!("{:?}", d)) } } #[derive(Default)] pub struct NoEmbeddedDomainCodec; impl DomainDecode for NoEmbeddedDomainCodec { fn decode_embedded<'de, R: Reader<'de> + ?Sized>( &mut self, _r: &mut R, _read_annotations: bool, ) -> io::Result { Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here")) } } impl DomainEncode for NoEmbeddedDomainCodec { fn encode_embedded( &mut self, _w: &mut dyn Writer, _d: &D, ) -> io::Result<()> { Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here")) } } #[derive(Default)] pub struct IOValueDomainCodec; impl Domain for IOValue { type Decode = IOValueDomainCodec; type Encode = IOValueDomainCodec; } impl DomainDecode for IOValueDomainCodec { fn decode_embedded<'de, R: Reader<'de> + ?Sized>( &mut self, r: &mut R, read_annotations: bool, ) -> io::Result { Ok(r.next_iovalue(read_annotations)?) } } impl DomainEncode for IOValueDomainCodec { fn encode_embedded( &mut self, w: &mut dyn Writer, d: &IOValue, ) -> io::Result<()> { d.write(w, self) } }