Skip to main content

mdbook_embedify/
parser.rs

1use pest::Parser;
2
3#[derive(Parser)]
4#[grammar = "assets/pests/parser.pest"]
5struct MacroParser;
6
7#[derive(Clone)]
8pub struct Placeholder {
9    pub key: String,
10    pub default: String,
11    pub method: String,
12}
13
14#[derive(Clone)]
15pub struct EmbedAppOption {
16    pub name: String,
17    pub value: String,
18}
19
20#[derive(Clone)]
21pub struct EmbedApp {
22    pub name: String,
23    pub options: Vec<EmbedAppOption>,
24}
25
26pub fn get_option(name: &str, options: Vec<EmbedAppOption>) -> Option<EmbedAppOption> {
27    options.iter().find(|option| option.name == name).cloned()
28}
29
30pub fn parse_placeholder(input: &str) -> Option<Placeholder> {
31    if let Ok(pairs) = MacroParser::parse(Rule::placeholder, input) {
32        for pair in pairs {
33            if pair.as_rule() != Rule::placeholder {
34                continue;
35            }
36
37            let mut placeholder = Placeholder {
38                key: String::new(),
39                default: String::new(),
40                method: String::new(),
41            };
42
43            for inner_pair in pair.into_inner() {
44                match inner_pair.as_rule() {
45                    Rule::placeholder_method => {
46                        placeholder.method = inner_pair.as_str().to_string();
47                    }
48                    Rule::placeholder_argument => {
49                        for arg_pair in inner_pair.into_inner() {
50                            match arg_pair.as_rule() {
51                                Rule::placeholder_key => {
52                                    placeholder.key = arg_pair.as_str().to_string();
53                                }
54                                Rule::placeholder_default => {
55                                    placeholder.default = arg_pair
56                                        .as_str()
57                                        .trim_matches('"')
58                                        .trim_matches('\'')
59                                        .to_string();
60                                }
61                                _ => {}
62                            }
63                        }
64                    }
65                    _ => {}
66                }
67            }
68
69            return Some(placeholder);
70        }
71    }
72
73    None
74}
75
76pub fn parse_app(input: &str) -> Option<EmbedApp> {
77    if let Ok(pairs) = MacroParser::parse(Rule::embed, input) {
78        for pair in pairs {
79            if pair.as_rule() != Rule::embed {
80                continue;
81            }
82
83            let mut app = EmbedApp {
84                name: String::new(),
85                options: Vec::new(),
86            };
87
88            for inner_pair in pair.into_inner() {
89                match inner_pair.as_rule() {
90                    Rule::embed_name => {
91                        app.name = inner_pair.as_str().to_string();
92                    }
93                    Rule::embed_options => {
94                        for option_pair in inner_pair.into_inner() {
95                            match option_pair.as_rule() {
96                                Rule::embed_option => {
97                                    let mut option = EmbedAppOption {
98                                        name: String::new(),
99                                        value: String::new(),
100                                    };
101
102                                    for opt_pair in option_pair.into_inner() {
103                                        match opt_pair.as_rule() {
104                                            Rule::embed_option_name => {
105                                                option.name = opt_pair.as_str().to_string();
106                                            }
107                                            Rule::embed_option_value => {
108                                                option.value = opt_pair
109                                                    .as_str()
110                                                    .trim_matches('"')
111                                                    .trim_matches('\'')
112                                                    .to_string();
113                                            }
114                                            _ => {}
115                                        }
116                                    }
117
118                                    app.options.push(option);
119                                }
120                                _ => {}
121                            }
122                        }
123                    }
124                    _ => {}
125                }
126            }
127
128            return Some(app);
129        }
130    }
131
132    None
133}