use std::io; use super::Reader; use super::Writer; pub trait Domain<'de>: std::fmt::Debug + Eq + std::hash::Hash + Ord + Clone { type Decode: DomainDecode<'de, Self> + Default; type Encode: DomainEncode<'de, Self> + Default; } pub trait DomainDecode<'de, D: Domain<'de>> { fn decode_embedded + ?Sized>( &mut self, r: &mut R, read_annotations: bool, ) -> io::Result; } pub trait DomainEncode<'de, D: Domain<'de>> { fn encode_embedded( &mut self, w: &mut dyn Writer, d: &D, ) -> io::Result<()>; } impl<'a, 'de, D: Domain<'de>, T: DomainDecode<'de, D>> DomainDecode<'de, D> for &'a mut T { fn decode_embedded + ?Sized>( &mut self, r: &mut R, read_annotations: bool, ) -> io::Result { (**self).decode_embedded(r, read_annotations) } } impl<'a, 'de, D: Domain<'de>, T: DomainEncode<'de, D>> DomainEncode<'de, D> 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<'de, D: Domain<'de>> DomainDecode<'de, D> for DefaultDomainCodec { fn decode_embedded + ?Sized>( &mut self, r: &mut R, read_annotations: bool, ) -> io::Result { D::Decode::default().decode_embedded(r, read_annotations) } } impl<'de, D: Domain<'de>> DomainEncode<'de, D> 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<'de, Err: Into, D: Domain<'de> + std::str::FromStr> DomainDecode<'de, D> for DebugDomainCodec { fn decode_embedded + ?Sized>( &mut self, r: &mut R, _read_annotations: bool, ) -> io::Result { r.next_str()?.parse().map_err(|e: Err| e.into()) } } impl<'de, D: Domain<'de>> DomainEncode<'de, D> 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<'de, D: Domain<'de>> DomainDecode<'de, D> for NoEmbeddedDomainCodec { fn decode_embedded + ?Sized>( &mut self, _r: &mut R, _read_annotations: bool, ) -> io::Result { Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here")) } } impl<'de, D: Domain<'de>> DomainEncode<'de, D> 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")) } }