1use pest::error::Error;
2pub use pest::iterators::{Pair, Pairs};
3
4pub use pest::pratt_parser::{Assoc, Op, PrattParser};
5pub use pest::{Parser, Span};
6pub use pest_derive::Parser;
7
8mod parsing;
9pub use parsing::get_pax_pratt_parser;
10pub mod formatting;
11
12pub mod deserializer;
13pub mod interpreter;
14pub use deserializer::from_pax;
15pub mod helpers;
16
17pub use interpreter::{
18 computable::Computable, parse_pax_expression, property_resolution::DependencyCollector,
19};
20
21#[derive(Parser)]
22#[grammar = "pax.pest"]
23pub struct PaxParser;
24
25fn renamed_rules(rule: &Rule) -> String {
26 match rule {
27 Rule::EOI => "end of file".to_string(),
28 Rule::WHITESPACE => " ".to_string(),
29 Rule::comment => "comment".to_string(),
30 Rule::pax_component_definition => "component".to_string(),
31 Rule::root_tag_pair => "component tag, comment".to_string(),
32 Rule::any_tag_pair => "component tag, comment".to_string(),
33 Rule::open_tag => "opening component tag".to_string(),
34 Rule::closing_tag => "closing component tag".to_string(),
35 Rule::self_closing_tag => "component tag".to_string(),
36 Rule::matched_tag => "component tag".to_string(),
37 Rule::inner_nodes => "literal value, expression, component tag".to_string(),
38 Rule::identifier => "identifier".to_string(),
39 Rule::pascal_identifier => "identifier".to_string(),
40 Rule::event_id => "@HANDLER_NAME".to_string(),
41 Rule::attribute_key_value_pair => "setting key-value pair".to_string(),
42 Rule::attribute_event_binding => "handler binding".to_string(),
43 Rule::double_binding => "two-way binding".to_string(),
44 Rule::any_template_value => "literal value, literal object, expression, identifier".to_string(),
45 Rule::node_inner_content => "literal value or expression".to_string(),
46 Rule::string => "double quoted string".to_string(),
47 Rule::inner => "string".to_string(),
48 Rule::char => "char".to_string(),
49 Rule::settings_block_declaration => "settings block".to_string(),
50 Rule::selector_block => "selector block".to_string(),
51 Rule::literal_object => "literal object".to_string(),
52 Rule::selector => "selector (e.g. .CLASS_NAME or #ID_NAME)".to_string(),
53 Rule::settings_key_value_pair => "setting key-value pair".to_string(),
54 Rule::settings_event_binding => "handler binding".to_string(),
55 Rule::settings_key => "setting key (e.g. PROPERTY_NAME: )".to_string(),
56 Rule::settings_value => "literal value, literal object, {expression}".to_string(),
57 Rule::literal_function => "function name".to_string(),
58 Rule::silent_comma => ",".to_string(),
59 Rule::function_list => "function list (e.g. [handle_click, handle_click_again] )".to_string(),
60 Rule::literal_value => "literal value".to_string(),
61 Rule::literal_boolean => "boolean".to_string(),
62 Rule::literal_number_with_unit => "number with unit (e.g. 10px, 10%, 10deg, 10rad )".to_string(),
63 Rule::literal_number => "number".to_string(),
64 Rule::literal_number_integer => "integer".to_string(),
65 Rule::literal_number_float => "float".to_string(),
66 Rule::literal_number_unit => "unit (px, %, rad, deg)".to_string(),
67 Rule::literal_tuple => "tuple".to_string(),
68 Rule::literal_tuple_access => "tuple access".to_string(),
69 Rule::literal_enum_value => "enum".to_string(),
70 Rule::literal_enum_args_list => "enum args list".to_string(),
71 Rule::literal_color => "color space function (e.g. rgb(255,255,255) ), color constant (e.g. SLATE )".to_string(),
72 Rule::literal_color_space_func => "color space function (e.g. rgb(), hsl(), rgba(), hsla())".to_string(),
73 Rule::literal_color_channel => "integers 0-255, 0-100%, or arbitrary numeric deg/rad ".to_string(),
74 Rule::xo_color_space_func => "color space function (e.g. rgb(), hsl(), rgba(), hsla())".to_string(),
75 Rule::literal_color_const => "color constant (see docs.pax.dev/colors)".to_string(),
76 Rule::expression_body => "expression".to_string(),
77 Rule::expression_wrapped => "{ expression }".to_string(),
78 Rule::expression_grouped => "( expression )".to_string(),
79 Rule::xo_primary => "(expression), color space function, enum, function call, range, tuple, list, literal, identifier".to_string(),
80 Rule::xo_prefix => "- , !".to_string(),
81 Rule::xo_neg => "-".to_string(),
82 Rule::xo_bool_not => "!".to_string(),
83 Rule::xo_infix => "+, -, *, /, %, ^, ==, !=, <, <=, >, >=, &&, ||".to_string(),
84 Rule::xo_add => "+".to_string(),
85 Rule::xo_bool_and => "&&".to_string(),
86 Rule::xo_bool_or => "||".to_string(),
87 Rule::xo_div => "/".to_string(),
88 Rule::xo_exp => "^".to_string(),
89 Rule::xo_mod => "%".to_string(),
90 Rule::xo_mul => "*".to_string(),
91 Rule::xo_rel_eq => "==".to_string(),
92 Rule::xo_rel_gt => ">".to_string(),
93 Rule::xo_rel_gte => ">=".to_string(),
94 Rule::xo_rel_lt => "<".to_string(),
95 Rule::xo_rel_lte => "<=".to_string(),
96 Rule::xo_rel_neq => "!=".to_string(),
97 Rule::xo_sub => "-".to_string(),
98 Rule::xo_tern_then => "then".to_string(),
99 Rule::xo_tern_else => "else".to_string(),
100 Rule::xo_range => "range (e.g. 0..5 or i..j)".to_string(),
101 Rule::xo_range_exclusive => "..".to_string(),
102 Rule::xo_literal => "literal value".to_string(),
103 Rule::xo_object => "literal object".to_string(),
104 Rule::xo_object_settings_key_value_pair => "setting key-value pair".to_string(),
105 Rule::xo_symbol => "identifier".to_string(),
106 Rule::xo_tuple => "tuple (e.g. (1,2) )".to_string(),
107 Rule::xo_list => "list (e.g. [1,2] )".to_string(),
108 Rule::xo_enum_or_function_call => "enum, function call".to_string(),
109 Rule::xo_enum_or_function_args_list => "args list".to_string(),
110 Rule::statement_control_flow => "if, for, slot".to_string(),
111 Rule::statement_if => "if".to_string(),
112 Rule::statement_for => "for".to_string(),
113 Rule::statement_slot => "slot".to_string(),
114 Rule::statement_for_predicate_declaration => "for predicate (e.g. i, (elem,i) )".to_string(),
115 Rule::statement_for_source => "for source (e.g. 0..5 )".to_string(),
116 Rule::literal_list => "list".to_string(),
117 Rule::literal_option => "option".to_string(),
118 Rule::literal_some => "Some".to_string(),
119 Rule::literal_none => "None".to_string(),
120 Rule::literal_list_access => "list access".to_string(),
121 }
122}
123
124pub fn parse_pax_str(expected_rule: Rule, input: &str) -> Result<Pair<Rule>, String> {
125 let pairs = PaxParser::parse(expected_rule, input);
126 match pairs {
127 Ok(mut pairs) => {
128 let pair = pairs.next().unwrap();
129 Ok(pair)
130 }
131 Err(err) => {
132 let named_error = err.renamed_rules(renamed_rules);
133 Err(format!("{named_error}"))
134 }
135 }
136}
137
138pub fn parse_pax_err(expected_rule: Rule, input: &str) -> Result<Pair<Rule>, Error<Rule>> {
139 let pairs = PaxParser::parse(expected_rule, input);
140 match pairs {
141 Ok(mut pairs) => {
142 let pair = pairs.next().unwrap();
143 Ok(pair)
144 }
145 Err(err) => {
146 let named_error = err.renamed_rules(renamed_rules);
147 Err(named_error)
148 }
149 }
150}
151
152pub fn parse_pax_pairs(expected_rule: Rule, input: &str) -> Result<Pairs<Rule>, Error<Rule>> {
153 let pairs = PaxParser::parse(expected_rule, input);
154 match pairs {
155 Ok(pairs) => Ok(pairs),
156 Err(err) => {
157 let named_error = err.renamed_rules(renamed_rules);
158 Err(named_error)
159 }
160 }
161}