lib/grammar/ast/
node.rs

1use pest::iterators::Pairs;
2use serde::Serialize;
3
4use crate::grammar::parser::Rule;
5
6use super::action::*;
7use super::comment::*;
8use super::control::*;
9use super::test::*;
10
11#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
12#[serde(untagged)]
13pub enum Node {
14    ControlRequire(ControlRequire),
15    ControlCondition(ControlCondition),
16    ControlStop(ControlStop),
17
18    ActionFileinto(ActionFileinto),
19    ActionRedirect(ActionRedirect),
20    ActionKeep(ActionKeep),
21    ActionDiscard(ActionDiscard),
22    ActionVacation(ActionVacation),
23    ActionReject(ActionReject),
24
25    TestAddress(TestAddress),
26    TestAllof(TestAllof),
27    TestAnyof(TestAnyof),
28    TestEnvelope(TestEnvelope),
29    TestExists(TestExists),
30    TestFalse(TestFalse),
31    TestHeader(TestHeader),
32    TestSize(TestSize),
33    TestTrue(TestTrue),
34
35    Comment(Comment),
36}
37
38pub fn tree<'n>(pairs: Pairs<Rule>, mut nodes: Vec<Box<Node>>) -> Vec<Box<Node>> {
39    let mut sieve = pairs.into_iter();
40
41    while let Some(pair) = sieve.next() {
42        // println!("while(pair): {:?}", pair.as_rule());
43
44        match pair.as_rule() {
45            Rule::EOI => {}
46            //
47            // Special rule for grouping test nodes
48            //
49            Rule::test => {
50                let children = tree(pair.clone().into_inner(), nodes.clone());
51                nodes = children;
52            }
53            _ => {
54                let node = match pair.as_rule() {
55                    // Controls
56                    Rule::control_condition => Node::ControlCondition(ControlCondition::from(pair)),
57                    Rule::control_require => Node::ControlRequire(ControlRequire::from(pair)),
58                    Rule::control_stop => Node::ControlStop(ControlStop::from(pair)),
59                    // Actions
60                    Rule::action_fileinto => Node::ActionFileinto(ActionFileinto::from(pair)),
61                    Rule::action_redirect => Node::ActionRedirect(ActionRedirect::from(pair)),
62                    Rule::action_keep => Node::ActionKeep(ActionKeep::from(pair)),
63                    Rule::action_discard => Node::ActionDiscard(ActionDiscard::from(pair)),
64                    Rule::action_vacation => Node::ActionVacation(ActionVacation::from(pair)),
65                    Rule::action_reject => Node::ActionReject(ActionReject::from(pair)),
66                    // Tests
67                    Rule::test_address => Node::TestAddress(TestAddress::from(pair)),
68                    Rule::test_allof => Node::TestAllof(TestAllof::from(pair)),
69                    Rule::test_anyof => Node::TestAnyof(TestAnyof::from(pair)),
70                    Rule::test_envelope => Node::TestEnvelope(TestEnvelope::from(pair)),
71                    Rule::test_exists => Node::TestExists(TestExists::from(pair)),
72                    Rule::test_false => Node::TestFalse(TestFalse::from(pair)),
73                    Rule::test_header => Node::TestHeader(TestHeader::from(pair)),
74                    Rule::test_size => Node::TestSize(TestSize::from(pair)),
75                    Rule::test_true => Node::TestTrue(TestTrue::from(pair)),
76                    // Comment
77                    Rule::COMMENT => Node::Comment(Comment::from(pair)),
78                    _ => {
79                        unreachable!("Encountered unexpected rule {:?}", pair.as_rule())
80                    }
81                };
82
83                // nodes.push(Box::new(node));
84                nodes.push(Box::new(node));
85            }
86        }
87    }
88
89    nodes
90}