diff --git a/src/templater.rs b/src/templater.rs index e8f24e851..a070dc636 100644 --- a/src/templater.rs +++ b/src/templater.rs @@ -25,6 +25,20 @@ pub trait Template { fn format(&self, context: &C, formatter: &mut dyn Formatter) -> io::Result<()>; } +/// Template that supports list-like behavior. +pub trait ListTemplate: Template { + /// Concatenates items with the given separator. + fn join<'a>(self: Box, separator: Box + 'a>) -> Box + 'a> + where + Self: 'a, + C: 'a; + + /// Upcasts to the template type. + fn into_template<'a>(self: Box) -> Box + 'a> + where + Self: 'a; +} + pub trait IntoTemplate<'a, C> { fn into_template(self) -> Box + 'a>; } @@ -413,6 +427,35 @@ where } } +impl ListTemplate for ListPropertyTemplate +where + P: TemplateProperty, + P::Output: IntoIterator, + S: Template, + F: Fn(&C, &mut dyn Formatter, O) -> io::Result<()>, +{ + fn join<'a>(self: Box, separator: Box + 'a>) -> Box + 'a> + where + Self: 'a, + C: 'a, + { + // Once join()-ed, list-like API should be dropped. This is guaranteed by + // the return type. + Box::new(ListPropertyTemplate::new( + self.property, + separator, + self.format_item, + )) + } + + fn into_template<'a>(self: Box) -> Box + 'a> + where + Self: 'a, + { + self + } +} + pub struct ConditionalTemplate { pub condition: P, pub true_template: T,