use std::collections::HashMap; use std::convert::TryFrom; use std::fmt::{self, Debug, Display, Formatter}; use std::ops::{Add, AddAssign, Deref}; use std::rc::Rc; use super::{Str, Value}; use crate::diag::StrResult; use crate::exec::ExecContext; use crate::syntax::{Expr, SyntaxTree}; use crate::util::EcoString; /// A template value: `[*Hi* there]`. #[derive(Debug, Default, Clone)] pub struct Template(Rc>); impl Template { /// Create a new template from a vector of nodes. pub fn new(nodes: Vec) -> Self { Self(Rc::new(nodes)) } /// Iterate over the contained template nodes. pub fn iter(&self) -> std::slice::Iter { self.0.iter() } /// Repeat this template `n` times. pub fn repeat(&self, n: i64) -> StrResult { let count = usize::try_from(n) .ok() .and_then(|n| self.0.len().checked_mul(n)) .ok_or_else(|| format!("cannot repeat this template {} times", n))?; Ok(Self(Rc::new( self.iter().cloned().cycle().take(count).collect(), ))) } } impl Display for Template { fn fmt(&self, f: &mut Formatter) -> fmt::Result { f.pad("