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]]]")
}
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]]]")
}
}
#[derive(Clone)]
-pub enum TemplateValue {
+pub enum Value {
String(String),
Unsigned(u64),
Bool(bool),
- Collection(Vec<TemplateContext>),
- Context(TemplateContext),
+ Collection(Vec<Context>),
+ 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<String, TemplateValue>;
+pub type Context = HashMap<String, Value>;
-struct TemplateContextGetter {}
-impl TemplateContextGetter {
- fn get(context: &TemplateContext, path: &str) -> Option<TemplateValue> {
+struct ContextGetter {}
+impl ContextGetter {
+ fn get(context: &Context, path: &str) -> Option<Value> {
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<TemplateValue> {
+ fn recursively_get_value(context: &Context, path: &[&str]) -> Option<Value> {
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,
}
}
-pub struct ParsedTemplate {
+pub struct Parsed {
pub tokens: Vec<Token>,
}
-impl ParsedTemplate {
- pub fn render(&self, context: &TemplateContext) -> Result<String> {
- ParsedTemplate::render_tokens(&self.tokens, context)
+impl Parsed {
+ pub fn render(&self, context: &Context) -> Result<String> {
+ Parsed::render_tokens(&self.tokens, context)
}
- pub fn render_tokens(tokens: &Vec<Token>, context: &TemplateContext) -> Result<String> {
+ pub fn render_tokens(tokens: &Vec<Token>, context: &Context) -> Result<String> {
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());
}
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"),
)),
}?;
}
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"),
)),
}?;
}
}
}
-pub fn parse(template: &str) -> Option<ParsedTemplate> {
+pub fn parse(template: &str) -> Option<Parsed> {
let mut tokens = Vec::new();
tokenize(template, &mut tokens).ok()?;
- Some(ParsedTemplate { tokens })
+ Some(Parsed { tokens })
}
fn tokenize(template: &str, tokens: &mut Vec<Token>) -> Result<()> {