preserves_schema/support/
mod.rs1#[doc(hidden)]
4pub use lazy_static::lazy_static;
6
7pub use preserves;
8pub use preserves::value::boundary as B;
9pub use preserves::value::Reader;
10
11pub mod interpret;
12
13use preserves::value::ArcValue;
14use preserves::value::Domain;
15use preserves::value::IOValue;
16use preserves::value::NestedValue;
17use preserves::value::NoEmbeddedDomainCodec;
18use preserves::value::Value;
19
20use std::convert::From;
21use std::convert::Into;
22use std::convert::TryFrom;
23use std::io;
24use std::sync::Arc;
25
26use thiserror::Error;
27
28pub trait NestedValueCodec {} impl NestedValueCodec for () {}
31
32pub trait Parse<L, Value: NestedValue>: Sized {
36 fn parse(language: L, value: &Value) -> Result<Self, ParseError>;
39}
40
41impl<'a, T: NestedValueCodec, Value: NestedValue> Parse<&'a T, Value> for Value {
42 fn parse(_language: &'a T, value: &Value) -> Result<Self, ParseError> {
43 Ok(value.clone())
44 }
45}
46
47pub trait Unparse<L, Value: NestedValue> {
50 fn unparse(&self, language: L) -> Value;
52}
53
54impl<'a, T: NestedValueCodec, Value: NestedValue> Unparse<&'a T, Value> for Value {
55 fn unparse(&self, _language: &'a T) -> Value {
56 self.clone()
57 }
58}
59
60pub trait Codec<N: NestedValue> {
63 fn parse<'a, T: Parse<&'a Self, N>>(&'a self, value: &N) -> Result<T, ParseError>;
66 fn unparse<'a, T: Unparse<&'a Self, N>>(&'a self, value: &T) -> N;
68}
69
70impl<L, N: NestedValue> Codec<N> for L {
71 fn parse<'a, T: Parse<&'a L, N>>(&'a self, value: &N) -> Result<T, ParseError> {
72 T::parse(self, value)
73 }
74
75 fn unparse<'a, T: Unparse<&'a L, N>>(&'a self, value: &T) -> N {
76 value.unparse(self)
77 }
78}
79
80pub trait Deserialize<N: NestedValue>
86where
87 Self: Sized,
88{
89 fn deserialize<'de, R: Reader<'de, N>>(r: &mut R) -> Result<Self, ParseError>;
90}
91
92pub fn decode_lit<N: NestedValue>(bs: &[u8]) -> io::Result<N> {
95 preserves::value::packed::from_bytes(bs, NoEmbeddedDomainCodec)
96}
97
98pub fn decode_embedded<D: Domain>(v: &IOValue) -> Result<ArcValue<Arc<D>>, ParseError>
101where
102 for<'a> D: TryFrom<&'a IOValue, Error = ParseError>,
103{
104 v.copy_via(&mut |d| Ok(Value::Embedded(Arc::new(D::try_from(d)?))))
105}
106
107pub fn encode_embedded<D: Domain>(v: &ArcValue<Arc<D>>) -> IOValue
110where
111 for<'a> IOValue: From<&'a D>,
112{
113 v.copy_via::<_, _, std::convert::Infallible>(&mut |d| Ok(Value::Embedded(IOValue::from(d))))
114 .unwrap()
115}
116
117#[derive(Error, Debug)]
119pub enum ParseError {
120 #[error("Input not conformant with Schema: {0}")]
122 ConformanceError(&'static str),
123 #[error(transparent)]
125 Preserves(preserves::error::Error),
126}
127
128impl From<preserves::error::Error> for ParseError {
129 fn from(v: preserves::error::Error) -> Self {
130 match v {
131 preserves::error::Error::Expected(_, _) => {
132 ParseError::ConformanceError("preserves::error::Error::Expected")
133 }
134 _ => ParseError::Preserves(v),
135 }
136 }
137}
138
139impl From<io::Error> for ParseError {
140 fn from(v: io::Error) -> Self {
141 preserves::error::Error::from(v).into()
142 }
143}
144
145impl From<ParseError> for io::Error {
146 fn from(v: ParseError) -> Self {
147 match v {
148 ParseError::ConformanceError(_) => io::Error::new(io::ErrorKind::InvalidData, v),
149 ParseError::Preserves(e) => e.into(),
150 }
151 }
152}
153
154impl ParseError {
155 pub fn conformance_error(context: &'static str) -> Self {
157 ParseError::ConformanceError(context)
158 }
159
160 pub fn is_conformance_error(&self) -> bool {
162 return if let ParseError::ConformanceError(_) = self {
163 true
164 } else {
165 false
166 };
167 }
168}