mdbook_embedify/
parser.rs1use 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}