2020-04-06 17:16:18 +00:00
|
|
|
use pest::{error::Error, iterators::Pair, Parser};
|
|
|
|
|
|
|
|
use super::model::*;
|
|
|
|
|
|
|
|
#[derive(Parser)]
|
|
|
|
#[grammar = "formatter/spec.pest"]
|
|
|
|
struct IdentParser;
|
|
|
|
|
2020-07-07 22:45:32 +00:00
|
|
|
fn _parse_value(value: Pair<Rule>) -> FormatElement {
|
|
|
|
match value.as_rule() {
|
|
|
|
Rule::text => FormatElement::Text(_parse_text(value).into()),
|
|
|
|
Rule::variable => FormatElement::Variable(_parse_variable(value).into()),
|
|
|
|
Rule::textgroup => FormatElement::TextGroup(_parse_textgroup(value)),
|
|
|
|
Rule::conditional => {
|
|
|
|
FormatElement::Conditional(_parse_format(value.into_inner().next().unwrap()))
|
|
|
|
}
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-06 17:16:18 +00:00
|
|
|
fn _parse_textgroup(textgroup: Pair<Rule>) -> TextGroup {
|
|
|
|
let mut inner_rules = textgroup.into_inner();
|
|
|
|
let format = inner_rules.next().unwrap();
|
|
|
|
let style = inner_rules.next().unwrap();
|
|
|
|
|
|
|
|
TextGroup {
|
|
|
|
format: _parse_format(format),
|
|
|
|
style: _parse_style(style),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn _parse_variable(variable: Pair<Rule>) -> &str {
|
|
|
|
variable.into_inner().next().unwrap().as_str()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn _parse_text(text: Pair<Rule>) -> String {
|
2020-07-07 22:45:32 +00:00
|
|
|
text.into_inner()
|
|
|
|
.map(|pair| pair.as_str().chars())
|
|
|
|
.flatten()
|
|
|
|
.collect()
|
2020-04-06 17:16:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn _parse_format(format: Pair<Rule>) -> Vec<FormatElement> {
|
2020-07-07 22:45:32 +00:00
|
|
|
format.into_inner().map(_parse_value).collect()
|
2020-04-06 17:16:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn _parse_style(style: Pair<Rule>) -> Vec<StyleElement> {
|
2020-07-07 22:45:32 +00:00
|
|
|
style
|
|
|
|
.into_inner()
|
|
|
|
.map(|pair| match pair.as_rule() {
|
|
|
|
Rule::string => StyleElement::Text(pair.as_str().into()),
|
|
|
|
Rule::variable => StyleElement::Variable(_parse_variable(pair).into()),
|
2020-04-06 17:16:18 +00:00
|
|
|
_ => unreachable!(),
|
2020-07-07 22:45:32 +00:00
|
|
|
})
|
|
|
|
.collect()
|
2020-04-06 17:16:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn parse(format: &str) -> Result<Vec<FormatElement>, Error<Rule>> {
|
2020-07-07 22:45:32 +00:00
|
|
|
IdentParser::parse(Rule::expression, format).map(|pairs| {
|
|
|
|
pairs
|
|
|
|
.take_while(|pair| pair.as_rule() != Rule::EOI)
|
|
|
|
.map(_parse_value)
|
|
|
|
.collect()
|
|
|
|
})
|
2020-04-06 17:16:18 +00:00
|
|
|
}
|