X-Git-Url: https://git.r.bdr.sh/rbdr/blog/blobdiff_plain/d7fef30ac3f539975ef9edbba8e0af4a4e9ff3de..b17907faf8d9693cef94a6048d802bd4ced9102f:/src/template.rs?ds=inline diff --git a/src/template.rs b/src/template.rs index 9bd8644..57a2571 100644 --- a/src/template.rs +++ b/src/template.rs @@ -30,15 +30,15 @@ pub enum Token { impl std::fmt::Display for Token { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { - Token::Text(label) => write!(f, "Text {}", label), - Token::DisplayDirective { content } => write!(f, "DisplayDirective {}", content), + Token::Text(label) => write!(f, "Text {label}"), + Token::DisplayDirective { content } => write!(f, "DisplayDirective {content}"), Token::ConditionalDirective { condition, children, } => { - write!(f, "ConditionalDirective {} [[[\n", condition)?; + writeln!(f, "ConditionalDirective {condition} [[[")?; for child in children { - write!(f, "\t{}\n", child)?; + writeln!(f, "\t{child}")?; } write!(f, "\n]]]") } @@ -47,9 +47,9 @@ impl std::fmt::Display for Token { member_label, children, } => { - write!(f, "{} in {}\n", collection, member_label)?; + writeln!(f, "{collection} in {member_label}")?; for child in children { - write!(f, "\t{}\n", child)?; + writeln!(f, "\t{child}")?; } write!(f, "\n]]]") } @@ -58,38 +58,38 @@ impl std::fmt::Display for Token { } #[derive(Clone)] -pub enum TemplateValue { +pub enum Value { String(String), Unsigned(u64), Bool(bool), - Collection(Vec), - Context(TemplateContext), + Collection(Vec), + Context(Context), } -impl TemplateValue { +impl Value { fn render(&self) -> String { match self { - TemplateValue::String(string) => string.to_string(), - TemplateValue::Unsigned(number) => format!("{}", number), - TemplateValue::Bool(bool) => format!("{}", bool), - _ => "".to_string(), + Value::String(string) => string.to_string(), + Value::Unsigned(number) => format!("{number}"), + Value::Bool(bool) => format!("{bool}"), + _ => String::new(), } } } -pub type TemplateContext = HashMap; +pub type Context = HashMap; -struct TemplateContextGetter {} -impl TemplateContextGetter { - fn get(context: &TemplateContext, path: &str) -> Option { +struct ContextGetter {} +impl ContextGetter { + fn get(context: &Context, path: &str) -> Option { let path_parts: Vec<&str> = path.split('.').collect(); - TemplateContextGetter::recursively_get_value(context, &path_parts) + ContextGetter::recursively_get_value(context, &path_parts) } - fn recursively_get_value(context: &TemplateContext, path: &[&str]) -> Option { + fn recursively_get_value(context: &Context, path: &[&str]) -> Option { match context.get(path[0]) { - Some(TemplateValue::Context(next)) if path.len() > 1 => { - TemplateContextGetter::recursively_get_value(next, &path[1..]) + Some(Value::Context(next)) if path.len() > 1 => { + ContextGetter::recursively_get_value(next, &path[1..]) } Some(value) if path.len() == 1 => Some(value.clone()), _ => None, @@ -97,23 +97,23 @@ impl TemplateContextGetter { } } -pub struct ParsedTemplate { +pub struct Parsed { pub tokens: Vec, } -impl ParsedTemplate { - pub fn render(&self, context: &TemplateContext) -> Result { - ParsedTemplate::render_tokens(&self.tokens, context) +impl Parsed { + pub fn render(&self, context: &Context) -> Result { + Parsed::render_tokens(&self.tokens, context) } - pub fn render_tokens(tokens: &Vec, context: &TemplateContext) -> Result { + pub fn render_tokens(tokens: &Vec, context: &Context) -> Result { let mut rendered_template: String = String::new(); for token in tokens { match token { - Token::Text(contents) => rendered_template.push_str(&contents), + Token::Text(contents) => rendered_template.push_str(contents), Token::DisplayDirective { content } => { - let value = TemplateContextGetter::get(context, &content).ok_or_else(|| { - Error::new(Other, format!("{} is not a valid key", content)) + let value = ContextGetter::get(context, content).ok_or_else(|| { + Error::new(Other, format!("{content} is not a valid key")) })?; rendered_template.push_str(&value.render()); } @@ -128,22 +128,21 @@ impl ParsedTemplate { condition = condition[1..].to_string(); } - let value = - TemplateContextGetter::get(context, &condition).ok_or_else(|| { - Error::new(Other, format!("{} is not a valid key", condition)) - })?; + let value = ContextGetter::get(context, &condition).ok_or_else(|| { + Error::new(Other, format!("{condition} is not a valid key")) + })?; match value { - TemplateValue::Bool(value) => { + Value::Bool(value) => { if negator ^ value { rendered_template - .push_str(&ParsedTemplate::render_tokens(children, context)?) + .push_str(&Parsed::render_tokens(children, context)?); } Ok(()) } _ => Err(Error::new( Other, - format!("{} is not a boolean value", condition), + format!("{condition} is not a boolean value"), )), }?; } @@ -152,29 +151,24 @@ impl ParsedTemplate { member_label, children, } => { - let value = - TemplateContextGetter::get(context, &collection).ok_or_else(|| { - Error::new(Other, format!("{} is not a valid key", collection)) - })?; + let value = ContextGetter::get(context, collection).ok_or_else(|| { + Error::new(Other, format!("{collection} is not a valid key")) + })?; match value { - TemplateValue::Collection(collection) => { + Value::Collection(collection) => { for member in collection { let mut child_context = context.clone(); - child_context.insert( - member_label.to_string(), - TemplateValue::Context(member), - ); - rendered_template.push_str(&ParsedTemplate::render_tokens( - &children, - &child_context, - )?) + child_context + .insert(member_label.to_string(), Value::Context(member)); + rendered_template + .push_str(&Parsed::render_tokens(children, &child_context)?); } Ok(()) } _ => Err(Error::new( Other, - format!("{} is not a collection", collection), + format!("{collection} is not a collection"), )), }?; } @@ -184,10 +178,10 @@ impl ParsedTemplate { } } -pub fn parse(template: &str) -> Option { +pub fn parse(template: &str) -> Option { let mut tokens = Vec::new(); tokenize(template, &mut tokens).ok()?; - Some(ParsedTemplate { tokens }) + Some(Parsed { tokens }) } fn tokenize(template: &str, tokens: &mut Vec) -> Result<()> {