pub use lazy_static::lazy_static; pub use preserves; pub use preserves::value::Reader; pub use preserves::value::boundary as B; pub mod interpret; use preserves::value::ArcValue; use preserves::value::Domain; use preserves::value::IOValue; use preserves::value::NestedValue; use preserves::value::NoEmbeddedDomainCodec; use preserves::value::Value; use std::convert::From; use std::convert::Into; use std::convert::TryFrom; use std::io; use std::sync::Arc; use thiserror::Error; pub trait NestedValueCodec {} // marker trait impl NestedValueCodec for () {} pub trait Parse: Sized { fn parse(language: L, value: &Value) -> Result; } impl<'a, T: NestedValueCodec, Value: NestedValue> Parse<&'a T, Value> for Value { fn parse(_language: &'a T, value: &Value) -> Result { Ok(value.clone()) } } pub trait Unparse { fn unparse(&self, language: L) -> Value; } impl<'a, T: NestedValueCodec, Value: NestedValue> Unparse<&'a T, Value> for Value { fn unparse(&self, _language: &'a T) -> Value { self.clone() } } pub trait Codec { fn parse<'a, T: Parse<&'a Self, N>>(&'a self, value: &N) -> Result; fn unparse<'a, T: Unparse<&'a Self, N>>(&'a self, value: &T) -> N; } impl Codec for L { fn parse<'a, T: Parse<&'a L, N>>(&'a self, value: &N) -> Result { T::parse(self, value) } fn unparse<'a, T: Unparse<&'a L, N>>(&'a self, value: &T) -> N { value.unparse(self) } } pub trait Deserialize<'de, N: NestedValue, R: Reader<'de, N>> where Self: Sized { fn deserialize(r: &mut R) -> Result; } pub fn decode_lit(bs: &[u8]) -> io::Result { preserves::value::packed::from_bytes(bs, NoEmbeddedDomainCodec) } pub fn decode_embedded( v: &IOValue, ) -> Result>, ParseError> where for<'a> D: TryFrom<&'a IOValue, Error = ParseError> { v.copy_via(&mut |d| Ok(Value::Embedded(Arc::new(D::try_from(d)?)))) } pub fn encode_embedded( v: &ArcValue>, ) -> IOValue where for<'a> IOValue: From<&'a D> { v.copy_via::<_, _, std::convert::Infallible>( &mut |d| Ok(Value::Embedded(IOValue::from(d)))).unwrap() } #[derive(Error, Debug)] pub enum ParseError { #[error("Input not conformant with Schema: {0}")] ConformanceError(&'static str), #[error(transparent)] Preserves(preserves::error::Error), } impl From for ParseError { fn from(v: preserves::error::Error) -> Self { match v { preserves::error::Error::Expected(_, _) => ParseError::ConformanceError("preserves::error::Error::Expected"), _ => ParseError::Preserves(v), } } } impl From for ParseError { fn from(v: io::Error) -> Self { preserves::error::Error::from(v).into() } } impl From for io::Error { fn from(v: ParseError) -> Self { match v { ParseError::ConformanceError(_) => io::Error::new(io::ErrorKind::InvalidData, v), ParseError::Preserves(e) => e.into(), } } } impl ParseError { pub fn conformance_error(context: &'static str) -> Self { ParseError::ConformanceError(context) } pub fn is_conformance_error(&self) -> bool { return if let ParseError::ConformanceError(_) = self { true } else { false } } }