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 match pair.as_rule() {
45 Rule::EOI => {}
46 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 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 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 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 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));
85 }
86 }
87 }
88
89 nodes
90}