use mufmt::{Ast, Manifest};
use std::{convert::Infallible, fmt, num::ParseIntError};
struct Repeat<'fmt>(&'fmt str, u8);
#[derive(Debug)]
pub enum Error {
InvalidInt(ParseIntError),
MissingDelimeter,
}
impl<'fmt> Ast<'fmt> for Repeat<'fmt> {
type Error = Error;
fn from_expr(expr: &'fmt str) -> Result<Self, Self::Error> {
match expr.split_once(':') {
Some((left, right)) => {
let count = right.trim().parse().map_err(Error::InvalidInt)?;
Ok(Self(left.trim(), count))
}
None => Err(Error::MissingDelimeter),
}
}
}
impl<'fmt> fmt::Display for Repeat<'fmt> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for _ in 0..self.1 {
f.write_str(self.0)?;
}
Ok(())
}
}
pub struct Limit(u8);
impl Manifest<Repeat<'_>> for Limit {
type Error = Infallible;
fn manifest(&self, ast: &Repeat<'_>) -> Result<impl fmt::Display, Self::Error> {
let reps = ast.1.min(self.0);
Ok(Repeat(ast.0, reps))
}
}
#[test]
fn test() {
use mufmt::BorrowedTemplate;
let template = BorrowedTemplate::compile("{%: 7}!").unwrap();
assert_eq!(template.render(&Limit(10)).unwrap(), "%%%%%%%!");
assert_eq!(template.render(&Limit(3)).unwrap(), "%%%!");
}