use crate::{error::Error, format, template::Template, value::FormatArg};
use alloc::{string::String, vec::Vec};
pub struct Renderer<'a> {
template: &'a Template<'a>,
args: Vec<FormatArg<'a>>,
named: Vec<(&'a str, usize)>,
}
impl<'a> Renderer<'a> {
pub(crate) fn new(template: &'a Template<'a>) -> Self {
Self {
template,
args: Vec::new(),
named: Vec::new(),
}
}
pub fn arg<V: Into<FormatArg<'a>>>(&mut self, value: V) -> &mut Self {
self.args.push(value.into());
self
}
pub fn named<V: Into<FormatArg<'a>>>(&mut self, name: &'a str, value: V) -> &mut Self {
let index = self.args.len();
self.args.push(value.into());
self.named.push((name, index));
self
}
pub fn finish(&self) -> Result<String, Error> {
self.render_inner(true)
}
pub fn finish_lenient(&self) -> Result<String, Error> {
self.render_inner(false)
}
fn render_inner(&self, strict: bool) -> Result<String, Error> {
let mut output = String::new();
format::render(
&mut output,
&self.template.parsed,
&self.args,
&self.named,
strict,
)?;
Ok(output)
}
}