abe/
convert.rs

1// Copyright Anton Sol
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at https://mozilla.org/MPL/2.0/.
6use std::{fmt::Display, marker::PhantomData, ops::Deref, str::FromStr, string::FromUtf8Error};
7
8
9use serde::{Deserialize, Serialize};
10
11use crate::{ast::*, eval::*};
12
13/// Impl this to combine with [TypedABE] and get a parsable, typed, abe expression
14pub trait ABEValidator
15where
16    Self: TryFrom<ABList>,
17{
18    fn check(b: &[ABE]) -> Result<(), MatchError>;
19}
20
21/// A convenient type wrapper around expressions.
22/// When V impl [ABEValidator] you get `FromStr` and `TryFrom<[u8]>` and [Self::eval].
23/// The shape of the ABE result is checked before evaluation.
24/// Note that `TypedABE<Vec<u8>>` is very different then `TypedABE<String>`.
25/// The former consumes everything and concatenates all the seperators as standard bytes.
26/// The later expects no seperators
27#[derive(Clone, Default, PartialEq)]
28pub struct TypedABE<V>(pub Vec<ABE>, PhantomData<V>);
29impl<V> Serialize for TypedABE<V> {
30    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
31    where
32        S: serde::Serializer,
33    {
34        self.0.serialize(serializer)
35    }
36}
37impl<'de, V: ABEValidator> Deserialize<'de> for TypedABE<V> {
38    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
39    where
40        D: serde::Deserializer<'de>,
41    {
42        let v = Vec::<ABE>::deserialize(deserializer)?;
43
44        V::check(&v).map_err(|e| <D::Error as serde::de::Error>::custom(e.to_string()))?;
45        Ok(TypedABE(v, PhantomData))
46    }
47}
48impl From<Vec<ABE>> for TypedABE<Vec<u8>> {
49    fn from(value: Vec<ABE>) -> Self {
50        TypedABE(value, PhantomData)
51    }
52}
53
54impl<A: ABEValidator> TypedABE<A> {
55    pub fn unwrap(self) -> Vec<ABE>{
56        self.0
57    }
58    pub fn eval_default(
59        &self,
60        default: A,
61        ctx: &EvalCtx<impl Scope>,
62    ) -> Result<A, ABEError<<A as TryFrom<ABList>>::Error>> {
63        let ablst = eval(ctx, &self.0).map_err(ABEError::Eval)?;
64        if ablst.is_empty() {
65            return Ok(default);
66        }
67        ablst.try_into().map_err(ABEError::TryFrom)
68    }
69    pub fn eval(
70        &self,
71        ctx: &EvalCtx<impl Scope>,
72    ) -> Result<A, ABEError<<A as TryFrom<ABList>>::Error>> {
73        let ablst = eval(ctx, &self.0).map_err(ABEError::Eval)?;
74        ablst.try_into().map_err(ABEError::TryFrom)
75    }
76    pub fn from(value: Vec<ABE>) -> Result<Self, MatchError> {
77        A::check(&value)?;
78        Ok(TypedABE(value, PhantomData))
79    }
80    pub fn new_unchecked(it: impl IntoIterator<Item = ABE>) -> Self {
81        TypedABE(it.into_iter().collect(), PhantomData)
82    }
83    pub const fn from_unchecked(v: Vec<ABE>) -> Self {
84        TypedABE(v, PhantomData)
85    }
86}
87impl<A> TypedABE<A> {
88    pub fn try_as<T: ABEValidator>(self) -> Result<TypedABE<T>, MatchError> {
89        TypedABE::from(self.0)
90    }
91}
92
93impl<A> Deref for TypedABE<A> {
94    type Target = Vec<ABE>;
95    fn deref(&self) -> &Self::Target {
96        &self.0
97    }
98}
99impl<O: ABEValidator> TryFrom<&[ABE]> for TypedABE<O> {
100    type Error = ABEError<<O as TryFrom<ABList>>::Error>;
101    fn try_from(value: &[ABE]) -> Result<Self, Self::Error> {
102        O::check(value).map_err(ABEError::MatchError)?;
103        Ok(TypedABE(value.to_vec(), PhantomData))
104    }
105}
106impl<O> From<TypedABE<O>> for Expr {
107    fn from(val: TypedABE<O>) -> Self {
108        Expr::Lst(val.0)
109    }
110}
111impl<O> From<TypedABE<O>> for Vec<ABE> {
112    fn from(val: TypedABE<O>) -> Self {
113        val.0
114    }
115}
116impl<O: ABEValidator> TryFrom<&[u8]> for TypedABE<O> {
117    type Error = ABEError<O::Error>;
118    fn try_from(s: &[u8]) -> Result<Self, Self::Error> {
119        let abe = parse_abe_b(s).map_err(ABEError::Parse)?;
120        O::check(&abe).map_err(ABEError::MatchError)?;
121        Ok(TypedABE(abe, PhantomData))
122    }
123}
124impl<O: ABEValidator> FromStr for TypedABE<O> {
125    type Err = ABEError<O::Error>;
126    fn from_str(s: &str) -> Result<Self, Self::Err> {
127        s.as_bytes().try_into()
128    }
129}
130impl<O> Display for TypedABE<O> {
131    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132        self.0.iter().try_for_each(|v| Display::fmt(v, f))?;
133        Ok(())
134    }
135}
136impl<O> std::fmt::Debug for TypedABE<O> {
137    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
138        f.debug_list().entries(&self.0).finish()
139    }
140}
141
142/// Concatenate control characters as is
143impl ABEValidator for Vec<u8> {
144    fn check(_b: &[ABE]) -> Result<(), MatchError> {
145        Ok(())
146    }
147}
148impl ABEValidator for ABList {
149    fn check(_b: &[ABE]) -> Result<(), MatchError> {
150        Ok(())
151    }
152}
153pub type AnyABE = TypedABE<ABList>;
154impl From<Vec<ABE>> for AnyABE {
155    fn from(value: Vec<ABE>) -> Self {
156        TypedABE(value,PhantomData)
157    }
158}
159
160impl ABEValidator for String {
161    fn check(b: &[ABE]) -> Result<(), MatchError> {
162        let [_] = exact(b)?;
163        Ok(())
164    }
165}
166impl TryFrom<ABList> for String {
167    type Error = ABEError<FromUtf8Error>;
168    fn try_from(value: ABList) -> Result<Self, Self::Error> {
169        let b = value.into_exact_bytes().map_err(|_| {
170            ABEError::MatchError(MatchError {
171                at: "".into(),
172                err: MatchErrorKind::ExpectedExpr,
173            })
174        })?;
175        String::from_utf8(b).map_err(ABEError::TryFrom)
176    }
177}
178pub fn eval_vec<A: ABEValidator>(
179    v: Vec<TypedABE<A>>,
180    e: &EvalCtx<impl Scope>,
181) -> Result<Vec<A>, ABEError<<A as TryFrom<ABList>>::Error>> {
182    v.into_iter().map(|v| v.eval(e)).try_collect()
183}
184
185pub trait ToABE {
186    fn to_abe_str(&self) -> String {
187        let mut st = String::new();
188        self.write_abe(&mut |abe| st.push_str(&abe.to_string()));
189        st
190    }
191    fn to_abe(&self) -> Vec<ABE>{
192        let mut v = vec![];
193        self.write_abe(&mut |abe| v.push(abe));
194        v
195    }
196    fn write_abe(&self, out: &mut dyn FnMut(ABE)){
197        self.to_abe().into_iter().for_each(out)
198    }
199}
200
201/// colon seperated list
202#[derive(Clone)]
203pub struct CList(pub Vec<Vec<u8>>);
204impl ABEValidator for CList {
205    fn check(b: &[ABE]) -> Result<(), MatchError> {
206        for i in b{
207            if matches!(i,ABE::Ctr(_)) { is_fslash(i)?;}
208        }
209        Ok(())
210    }
211}
212impl TryFrom<ABList> for CList{
213    type Error = MatchErrorKind;
214    fn try_from(value: ABList) -> Result<Self, Self::Error> {
215        value.lst.into_iter()
216            .map(|(b,c)| if !matches!(c,None | Some(Ctr::Colon)) {Err(MatchErrorKind::ExpectedColon)}else {Ok(b)})
217            .try_collect()
218            .map(CList)
219    }
220}