pax_lang/
lib.rs

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}