serde_intermediate/de/
text.rs

1use crate::{
2    de::intermediate::{deserialize_as, DeserializeMode},
3    error::*,
4    value::intermediate::Intermediate,
5};
6use pest::{iterators::Pair, Parser};
7use pest_derive::Parser;
8use serde::de::DeserializeOwned;
9
10pub fn from_str<T>(value: &str) -> Result<T>
11where
12    T: DeserializeOwned,
13{
14    from_str_as(value, Default::default())
15}
16
17pub fn from_str_as<T>(value: &str, mode: DeserializeMode) -> Result<T>
18where
19    T: DeserializeOwned,
20{
21    let value = intermediate_from_str(value)?;
22    deserialize_as(&value, mode)
23}
24
25#[derive(Parser)]
26#[grammar = "de/text.grammar.pest"]
27struct TextParser;
28
29pub fn intermediate_from_str(content: &str) -> Result<Intermediate> {
30    let ast = TextParser::parse(Rule::main, content)
31        .map_err(|error| Error::Message(format!("{}", error)))?
32        .next()
33        .ok_or(Error::NoNextTokens)?;
34    parse(ast)
35}
36
37macro_rules! impl_parse {
38    ($variant:ident : $ast:expr) => {{
39        let t = $ast.into_inner().next().unwrap().as_str();
40        match t.parse() {
41            Ok(value) => Ok(Intermediate::$variant(value)),
42            Err(_) => Err(Error::CannotParse(t.to_owned())),
43        }
44    }};
45}
46
47fn parse(ast: Pair<Rule>) -> Result<Intermediate> {
48    match ast.as_rule() {
49        Rule::unit => Ok(Intermediate::Unit),
50        Rule::bool => match ast.as_str() {
51            "true" => Ok(Intermediate::Bool(true)),
52            "false" => Ok(Intermediate::Bool(false)),
53            t => Err(Error::InvalidTokens(t.to_owned())),
54        },
55        Rule::i8 => impl_parse!(I8: ast),
56        Rule::i16 => impl_parse!(I16: ast),
57        Rule::i32 => impl_parse!(I32: ast),
58        Rule::i64 => impl_parse!(I64: ast),
59        Rule::i128 => impl_parse!(I128: ast),
60        Rule::u8 => impl_parse!(U8: ast),
61        Rule::u16 => impl_parse!(U16: ast),
62        Rule::u32 => impl_parse!(U32: ast),
63        Rule::u64 => impl_parse!(U64: ast),
64        Rule::u128 => impl_parse!(U128: ast),
65        Rule::f32 => impl_parse!(F32: ast),
66        Rule::f64 => impl_parse!(F64: ast),
67        Rule::char => impl_parse!(Char: ast),
68        Rule::signed_integer => {
69            let t = ast.as_str();
70            match t.parse() {
71                Ok(value) => Ok(Intermediate::I64(value)),
72                Err(_) => Err(Error::CannotParse(t.to_owned())),
73            }
74        }
75        Rule::unsigned_integer => {
76            let t = ast.as_str();
77            match t.parse() {
78                Ok(value) => Ok(Intermediate::U64(value)),
79                Err(_) => Err(Error::CannotParse(t.to_owned())),
80            }
81        }
82        Rule::real => {
83            let t = ast.as_str();
84            match t.parse() {
85                Ok(value) => Ok(Intermediate::F64(value)),
86                Err(_) => Err(Error::CannotParse(t.to_owned())),
87            }
88        }
89        Rule::string => Ok(Intermediate::String(
90            ast.into_inner().next().unwrap().as_str().to_owned(),
91        )),
92        Rule::bytes => {
93            let t = ast.into_inner().next().unwrap().as_str();
94            let bytes = (0..t.len())
95                .step_by(2)
96                .map(|i| u8::from_str_radix(&t[i..(i + 2)], 16))
97                .collect::<std::result::Result<Vec<_>, _>>();
98            match bytes {
99                Ok(bytes) => Ok(Intermediate::Bytes(bytes)),
100                Err(_) => Err(Error::CannotParse(t.to_owned())),
101            }
102        }
103        Rule::none => Ok(Intermediate::Option(None)),
104        Rule::some => {
105            let value = parse(ast.into_inner().next().unwrap())?;
106            Ok(Intermediate::Option(Some(Box::new(value))))
107        }
108        Rule::unit_struct => Ok(Intermediate::UnitStruct),
109        Rule::newtype_struct => {
110            let value = parse(ast.into_inner().next().unwrap())?;
111            Ok(Intermediate::NewTypeStruct(Box::new(value)))
112        }
113        Rule::seq => {
114            let list = ast.into_inner().map(parse).collect::<Result<Vec<_>>>()?;
115            Ok(Intermediate::Seq(list))
116        }
117        Rule::tuple => {
118            let list = ast.into_inner().map(parse).collect::<Result<Vec<_>>>()?;
119            Ok(Intermediate::Tuple(list))
120        }
121        Rule::tuple_struct => {
122            let list = ast.into_inner().map(parse).collect::<Result<Vec<_>>>()?;
123            Ok(Intermediate::TupleStruct(list))
124        }
125        Rule::map => {
126            let pairs = ast
127                .into_inner()
128                .map(|ast| {
129                    let mut pairs = ast.into_inner();
130                    let key = parse(pairs.next().unwrap())?;
131                    let value = parse(pairs.next().unwrap())?;
132                    Ok((key, value))
133                })
134                .collect::<Result<Vec<_>>>()?;
135            Ok(Intermediate::Map(pairs))
136        }
137        Rule::structure => {
138            let pairs = ast
139                .into_inner()
140                .map(|ast| {
141                    let mut pairs = ast.into_inner();
142                    let key = pairs.next().unwrap().as_str().to_owned();
143                    let value = parse(pairs.next().unwrap())?;
144                    Ok((key, value))
145                })
146                .collect::<Result<Vec<_>>>()?;
147            Ok(Intermediate::Struct(pairs))
148        }
149        Rule::variant => {
150            let mut pairs = ast.into_inner();
151            let name = pairs.next().unwrap().as_str().to_owned();
152            let content = pairs.next().unwrap();
153            match content.as_rule() {
154                Rule::unit => Ok(Intermediate::UnitVariant(name)),
155                Rule::newtype_struct => Ok(Intermediate::NewTypeVariant(
156                    name,
157                    Box::new(parse(content)?),
158                )),
159                Rule::tuple => {
160                    let list = content
161                        .into_inner()
162                        .map(parse)
163                        .collect::<Result<Vec<_>>>()?;
164                    Ok(Intermediate::TupleVariant(name, list))
165                }
166                Rule::structure => {
167                    let pairs = content
168                        .into_inner()
169                        .map(|ast| {
170                            let mut pairs = ast.into_inner();
171                            let key = pairs.next().unwrap().as_str().to_owned();
172                            let value = parse(pairs.next().unwrap())?;
173                            Ok((key, value))
174                        })
175                        .collect::<Result<Vec<_>>>()?;
176                    Ok(Intermediate::StructVariant(name, pairs))
177                }
178                _ => Err(Error::InvalidTokens(content.as_str().to_owned())),
179            }
180        }
181        _ => Err(Error::InvalidTokens(ast.as_str().to_owned())),
182    }
183}