diff --git a/src/duster/mod.rs b/src/duster/mod.rs index 3840047..520bb61 100644 --- a/src/duster/mod.rs +++ b/src/duster/mod.rs @@ -6,3 +6,5 @@ mod parser; pub use node_invoker::run_node_dust; pub use node_invoker::NodeError; pub use node_invoker::Result; +pub use parser::template; +pub use parser::Template; diff --git a/src/duster/parser.rs b/src/duster/parser.rs index 117be9c..d3ae8cc 100644 --- a/src/duster/parser.rs +++ b/src/duster/parser.rs @@ -4,6 +4,7 @@ use nom::bytes::complete::tag; use nom::bytes::complete::take_until; use nom::combinator::map; use nom::combinator::recognize; +use nom::combinator::rest; use nom::combinator::value; use nom::multi::many0; use nom::multi::separated_list; @@ -55,6 +56,19 @@ enum Filter { JsonParse, } +struct Span<'a> { + contents: &'a str, +} + +pub struct Template<'a> { + elements: Vec>, +} + +enum TemplateElement<'a> { + TESpan(Span<'a>), + TETag(DustTag<'a>), +} + fn dust_tag(i: &str) -> IResult<&str, DustTag> { alt(( map(special, DustTag::DTSpecial), @@ -121,3 +135,22 @@ fn filter(i: &str) -> IResult<&str, Filter> { )), )(i) } + +/// Any text that is not a Dust element +fn span(i: &str) -> IResult<&str, Span> { + let (remaining, body) = alt((take_until("{"), rest))(i)?; + Ok((remaining, Span { contents: body })) +} + +pub fn template(i: &str) -> IResult<&str, Template> { + let (remaining, template_elements) = many0(alt(( + map(span, TemplateElement::TESpan), + map(dust_tag, TemplateElement::TETag), + )))(i)?; + Ok(( + remaining, + Template { + elements: template_elements, + }, + )) +}