1#[cfg(feature = "parser")]
2use pest::error::Error;
3#[cfg(feature = "parser")]
4pub use pest::iterators::{Pair, Pairs};
5
6#[cfg(feature = "parser")]
7pub use pest::pratt_parser::{Assoc, Op, PrattParser};
8#[cfg(feature = "parser")]
9pub use pest::{Parser, Span};
10#[cfg(feature = "parser")]
11pub use pest_derive::Parser;
12
13#[cfg(feature = "parser")]
14mod parsing;
15#[cfg(feature = "parser")]
16pub use parsing::get_pax_pratt_parser;
17#[cfg(feature = "parser")]
18pub mod formatting;
19
20#[cfg(feature = "parser")]
21pub mod deserializer;
22pub mod interpreter;
23#[cfg(feature = "parser")]
24pub use deserializer::from_pax;
25#[cfg(feature = "parser")]
26pub mod helpers;
27
28#[cfg(feature = "parser")]
29pub use interpreter::parse_pax_expression;
30pub use interpreter::{computable::Computable, property_resolution::DependencyCollector};
31
32#[cfg(feature = "parser")]
34#[derive(Parser)]
35#[grammar = "pax.pest"]
36pub struct PaxParser;
37
38#[cfg(feature = "parser")]
39fn renamed_rules(rule: &Rule) -> String {
40 match rule {
41 Rule::template_list_value => "template list entry".to_string(),
42 Rule::EOI => "end of file".to_string(),
43 Rule::WHITESPACE => " ".to_string(),
44 Rule::comment => "comment".to_string(),
45 Rule::pax_component_definition => "component".to_string(),
46 Rule::root_tag_pair => "component tag, comment".to_string(),
47 Rule::any_tag_pair => "component tag, comment".to_string(),
48 Rule::open_tag => "opening component tag".to_string(),
49 Rule::closing_tag => "closing component tag".to_string(),
50 Rule::self_closing_tag => "component tag".to_string(),
51 Rule::matched_tag => "component tag".to_string(),
52 Rule::inner_nodes => "literal value, expression, component tag".to_string(),
53 Rule::identifier => "identifier".to_string(),
54 Rule::pascal_identifier => "identifier".to_string(),
55 Rule::event_id => "@HANDLER_NAME".to_string(),
56 Rule::attribute_key_value_pair => "setting key-value pair".to_string(),
57 Rule::class_attribute => "class attribute".to_string(),
58 Rule::class_value => "string, string list, or expression".to_string(),
59 Rule::class_string_list => "class string list".to_string(),
60 Rule::attribute_transition_binding => "transition binding".to_string(),
61 Rule::attribute_event_binding => "handler binding".to_string(),
62 Rule::transition_id => "@in or @out".to_string(),
63 Rule::transition_binding_value => "timeline name or inline @timeline block".to_string(),
64 Rule::transition_inline_timeline_value => "inline transition timeline".to_string(),
65 Rule::transition_inline_timeline_body => "inline transition timeline body".to_string(),
66 Rule::double_binding => "two-way binding".to_string(),
67 Rule::any_template_value => "literal value, literal object, expression, identifier, @gradient".to_string(),
68 Rule::node_inner_content => "literal value or expression".to_string(),
69 Rule::string => "double quoted string".to_string(),
70 Rule::inner => "string".to_string(),
71 Rule::char => "char".to_string(),
72 Rule::settings_block_declaration => "settings block".to_string(),
73 Rule::settings_block_element => "settings block element".to_string(),
74 Rule::settings_conditional => "settings conditional".to_string(),
75 Rule::settings_conditional_body => "settings conditional body".to_string(),
76 Rule::settings_if_branch => "settings if branch".to_string(),
77 Rule::settings_else_if_branch => "settings else if branch".to_string(),
78 Rule::settings_else_branch => "settings else branch".to_string(),
79 Rule::selector_block => "selector block".to_string(),
80 Rule::literal_object => "literal object".to_string(),
81 Rule::selector => "selector (e.g. .CLASS_NAME or #ID_NAME)".to_string(),
82 Rule::settings_key_value_pair => "setting key-value pair".to_string(),
83 Rule::settings_event_binding => "handler binding".to_string(),
84 Rule::settings_key => "setting key (e.g. PROPERTY_NAME: )".to_string(),
85 Rule::settings_value => "literal value, literal object, {expression}, @gradient".to_string(),
86 Rule::timeline_block_declaration => "timeline block".to_string(),
87 Rule::timeline_block_setting => "timeline block setting".to_string(),
88 Rule::timeline_block_setting_value => "timeline block setting value".to_string(),
89 Rule::timeline_selector_block => "timeline selector block".to_string(),
90 Rule::timeline_selector_body => "timeline selector body".to_string(),
91 Rule::timeline_property_key_value_pair => "timeline property key-value pair".to_string(),
92 Rule::timeline_inline_value => "@timeline block".to_string(),
93 Rule::timeline_track => "timeline track".to_string(),
94 Rule::timeline_keyframe => "timeline keyframe".to_string(),
95 Rule::timeline_keyframe_value => "timeline keyframe value".to_string(),
96 Rule::timeline_marker => "timeline marker (e.g. 24, 250ms, 5f, or 50%)".to_string(),
97 Rule::timeline_percent => "percent marker (e.g. 50%)".to_string(),
98 Rule::timeline_duration => "duration marker (e.g. 250ms, 1s, or 5f)".to_string(),
99 Rule::timeline_duration_unit => "duration unit (ms, s, f)".to_string(),
100 Rule::timeline_easing_curve => "timeline easing curve".to_string(),
101 Rule::timeline_target => "timeline target".to_string(),
102 Rule::timeline_local_target => "self or this".to_string(),
103 Rule::timeline_symbol => "identifier".to_string(),
104 Rule::gradient_inline_value => "@gradient block".to_string(),
105 Rule::gradient_body => "gradient body".to_string(),
106 Rule::gradient_shape_block => "gradient shape block".to_string(),
107 Rule::gradient_shape_key => "linear, radial, or mesh".to_string(),
108 Rule::gradient_shape_settings => "gradient shape settings".to_string(),
109 Rule::gradient_shape_setting => "gradient shape setting".to_string(),
110 Rule::gradient_shape_setting_value => "gradient shape setting value".to_string(),
111 Rule::gradient_stop => "gradient stop".to_string(),
112 Rule::gradient_stop_marker => "gradient stop marker".to_string(),
113 Rule::gradient_stop_value => "gradient stop color".to_string(),
114 Rule::literal_function => "function name".to_string(),
115 Rule::silent_comma => ",".to_string(),
116 Rule::function_list => "function list (e.g. [handle_click, handle_click_again] )".to_string(),
117 Rule::literal_value => "literal value".to_string(),
118 Rule::literal_boolean => "boolean".to_string(),
119 Rule::literal_number_with_unit => "number with unit (e.g. 10px, 10%, 10deg, 10rad, 10ms, 1s, 5f )".to_string(),
120 Rule::literal_number => "number".to_string(),
121 Rule::literal_number_integer => "integer".to_string(),
122 Rule::literal_number_float => "float".to_string(),
123 Rule::literal_number_unit => "unit (px, %, rad, deg, ms, s, f)".to_string(),
124 Rule::literal_tuple => "tuple".to_string(),
125 Rule::literal_tuple_access => "tuple access".to_string(),
126 Rule::literal_enum_value => "enum".to_string(),
127 Rule::literal_enum_args_list => "enum args list".to_string(),
128 Rule::literal_color => "color space function (e.g. rgb(255,255,255) ), color constant (e.g. SLATE )".to_string(),
129 Rule::literal_color_space_func => "color space function (e.g. rgb(), hsl(), rgba(), hsla())".to_string(),
130 Rule::literal_color_channel => "integers 0-255, 0-100%, or arbitrary numeric deg/rad ".to_string(),
131 Rule::xo_color_space_func => "color space function (e.g. rgb(), hsl(), rgba(), hsla())".to_string(),
132 Rule::literal_color_const => "color constant (see docs.pax.dev/colors)".to_string(),
133 Rule::expression_body => "expression".to_string(),
134 Rule::expression_ternary => "ternary expression".to_string(),
135 Rule::expression_coalesce => "null coalescing expression".to_string(),
136 Rule::expression_binary => "binary expression".to_string(),
137 Rule::expression_wrapped => "{ expression }".to_string(),
138 Rule::expression_grouped => "( expression )".to_string(),
139 Rule::expression_grouped_unit => "unit suffix for grouped expression".to_string(),
140 Rule::xo_primary => "(expression), color space function, enum, function call, range, tuple, list, literal, identifier".to_string(),
141 Rule::xo_prefix => "- , !".to_string(),
142 Rule::xo_neg => "-".to_string(),
143 Rule::xo_bool_not => "!".to_string(),
144 Rule::xo_infix => "+, -, *, /, %%, ^, ==, !=, <, <=, >, >=, &&, ||, ??, ?, :".to_string(),
145 Rule::xo_add => "+".to_string(),
146 Rule::xo_bool_and => "&&".to_string(),
147 Rule::xo_bool_or => "||".to_string(),
148 Rule::xo_div => "/".to_string(),
149 Rule::xo_exp => "^".to_string(),
150 Rule::xo_mod => "%%".to_string(),
151 Rule::xo_mul => "*".to_string(),
152 Rule::xo_rel_eq => "==".to_string(),
153 Rule::xo_rel_gt => ">".to_string(),
154 Rule::xo_rel_gte => ">=".to_string(),
155 Rule::xo_rel_lt => "<".to_string(),
156 Rule::xo_rel_lte => "<=".to_string(),
157 Rule::xo_rel_neq => "!=".to_string(),
158 Rule::xo_sub => "-".to_string(),
159 Rule::xo_null_coalesce => "??".to_string(),
160 Rule::xo_tern_then => "?".to_string(),
161 Rule::xo_tern_else => ":".to_string(),
162 Rule::xo_range => "range (e.g. 0..5 or i..j)".to_string(),
163 Rule::xo_range_exclusive => "..".to_string(),
164 Rule::xo_literal => "literal value".to_string(),
165 Rule::xo_object => "literal object".to_string(),
166 Rule::xo_object_settings_key_value_pair => "setting key-value pair".to_string(),
167 Rule::xo_symbol => "identifier".to_string(),
168 Rule::xo_tuple => "tuple (e.g. (1,2) )".to_string(),
169 Rule::xo_list => "list (e.g. [1,2] )".to_string(),
170 Rule::xo_enum_or_function_call => "enum, function call".to_string(),
171 Rule::xo_enum_or_function_args_list => "args list".to_string(),
172 Rule::statement_control_flow => "if, for, slot".to_string(),
173 Rule::statement_if => "if".to_string(),
174 Rule::statement_if_branch => "if branch".to_string(),
175 Rule::statement_else_if_branch => "else if branch".to_string(),
176 Rule::statement_else_branch => "else branch".to_string(),
177 Rule::statement_for => "for".to_string(),
178 Rule::statement_slot => "slot".to_string(),
179 Rule::statement_for_predicate_declaration => "for predicate (e.g. i, (elem,i) )".to_string(),
180 Rule::statement_for_source => "for source (e.g. 0..5 )".to_string(),
181 Rule::statement_for_key => "for key expression (e.g. key item.id )".to_string(),
182 Rule::literal_list => "list".to_string(),
183 Rule::literal_option => "option".to_string(),
184 Rule::literal_some => "Some".to_string(),
185 Rule::literal_none => "None".to_string(),
186 Rule::literal_list_access => "list access".to_string(),
187 }
188}
189
190#[cfg(feature = "parser")]
192pub fn parse_pax_str(expected_rule: Rule, input: &str) -> Result<Pair<'_, Rule>, String> {
193 let pairs = PaxParser::parse(expected_rule, input);
194 match pairs {
195 Ok(mut pairs) => {
196 let pair = pairs.next().unwrap();
197 Ok(pair)
198 }
199 Err(err) => {
200 let named_error = err.renamed_rules(renamed_rules);
201 Err(format!("{named_error}"))
202 }
203 }
204}
205
206#[cfg(feature = "parser")]
208pub fn parse_pax_err(expected_rule: Rule, input: &str) -> Result<Pair<'_, Rule>, Error<Rule>> {
209 let pairs = PaxParser::parse(expected_rule, input);
210 match pairs {
211 Ok(mut pairs) => {
212 let pair = pairs.next().unwrap();
213 Ok(pair)
214 }
215 Err(err) => {
216 let named_error = err.renamed_rules(renamed_rules);
217 Err(named_error)
218 }
219 }
220}
221
222#[cfg(feature = "parser")]
224pub fn parse_pax_pairs(expected_rule: Rule, input: &str) -> Result<Pairs<'_, Rule>, Error<Rule>> {
225 let pairs = PaxParser::parse(expected_rule, input);
226 match pairs {
227 Ok(pairs) => Ok(pairs),
228 Err(err) => {
229 let named_error = err.renamed_rules(renamed_rules);
230 Err(named_error)
231 }
232 }
233}