use crate::{error::Error, format, template::Template, value::FormatValue};
use std::fmt::{Debug, Display};
pub struct Renderer<'a> {
template: &'a Template,
args: Vec<&'a dyn FormatValue>,
named: Vec<(&'a str, usize)>,
}
impl<'a> Renderer<'a> {
pub(crate) fn new(template: &'a Template) -> Self {
Self {
template,
args: Vec::new(),
named: Vec::new(),
}
}
#[inline]
pub fn arg(&mut self, value: &'a (impl Display + Debug)) -> &mut Self {
self.args.push(value as &dyn FormatValue);
self
}
#[inline]
pub fn named(&mut self, name: &'a str, value: &'a (impl Display + Debug)) -> &mut Self {
let index = self.args.len();
self.args.push(value as &dyn FormatValue);
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 source = self.template.source();
let mut output = String::with_capacity(source.len());
format::render(
&mut output,
source,
self.template.parsed(),
&self.args,
&self.named,
strict,
)?;
Ok(output)
}
}