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())
}
}