mist_parser/parser/common/
mod.rs1pub mod decl;
2pub mod expr;
3pub mod statement;
4pub mod types;
5
6use crate::{
7 Rule,
8 ast::*,
9 ast_ensure, ast_expr,
10 error::{AstError, AstResult, IntoErr, collect_recovered, collect_recovered_map},
11 parser::{consume_rule, listen_rule},
12};
13
14impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Identifier {
15 type Error = AstError<'a, Self>;
16
17 fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
18 ast_ensure!(pair, Rule::identifier => {
19 Ok(Identifier(pair.as_str().to_string()))
20 })
21 }
22}
23
24impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Path {
25 type Error = AstError<'a, Self>;
26
27 fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
28 match pair.as_rule() {
29 Rule::static_path => Ok(Path(collect_recovered(pair.into_inner()).get()?)),
30 _ => AstError::bug_unimplemented(pair),
31 }
32 }
33}
34
35impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Literal {
36 type Error = AstError<'a, Self>;
37
38 fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
39 let rule = pair.as_rule();
40 let mut inner = pair.clone().into_inner();
41
42 Ok(match rule {
43 Rule::primary => Self::try_from(inner.next().unwrap())?,
44 Rule::literal => Self::try_from(inner.next().unwrap())?,
45 Rule::integer => Literal::Int(pair.as_str().parse::<i64>().unwrap()),
46 Rule::float => Literal::Float(pair.as_str().parse::<f64>().unwrap()),
47 Rule::boolean => Literal::Bool(pair.as_str().parse::<bool>().unwrap()),
48 Rule::string_lit => Literal::String(inner.as_str().to_string()),
49 Rule::tuple => Literal::Tuple(collect_recovered(inner).get()?),
50 _ => return AstError::bug_unimplemented(pair),
51 })
52 }
53}
54
55impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Pattern {
56 type Error = AstError<'a, Self>;
57
58 fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
59 let rule = pair.as_rule();
60 let mut inner = pair.clone().into_inner();
61
62 match rule {
63 Rule::tuple_pattern => ast_expr!(Pattern::Tuple(collect_recovered_map(inner, |v| {
64 Self::try_from(v).map(Box::new)
65 }))),
66
67 Rule::named_tuple_pattern => ast_expr!(Pattern::NamedTuple(
68 Path::try_from(inner.next().unwrap()),
69 collect_recovered_map(inner, |v| Self::try_from(v).map(Box::new)),
70 )),
71
72 Rule::struct_pattern => ast_expr!(Pattern::Struct(
73 Path::try_from(inner.next().unwrap()),
74 collect_recovered_map(inner, |v| Self::try_from(v).map(Box::new)),
75 )),
76
77 Rule::literal => ast_expr!(Pattern::Literal(pair.try_into())),
78
79 Rule::path_pattern => ast_expr!(Pattern::Path(
80 Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult<'_, bool>,
81 inner.next().unwrap().try_into()
82 )),
83
84 _ => AstError::bug_unimplemented(pair),
85 }
86 }
87}
88
89impl<'a> TryFrom<&mut pest::iterators::Pairs<'a, Rule>> for Visibility {
90 type Error = AstError<'a, Self>;
91
92 fn try_from(pairs: &mut pest::iterators::Pairs<'a, Rule>) -> Result<Self, Self::Error> {
93 Ok(consume_rule(pairs, Rule::visibility)
94 .map(|pair| -> Result<Visibility, AstError<'a, Self>> {
95 if let Some(path) = pair.into_inner().next() {
96 ast_expr!(Visibility::PublicTarget(Path::try_from(path)))
97 } else {
98 Ok(Visibility::Public)
99 }
100 })
101 .transpose()?
102 .unwrap_or_else(|| Visibility::Private))
103 }
104}