mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-18 18:27:38 +00:00
templater: add trait that represents a mapped template
A mapped template is basically a combined function that takes context: &C, extracts Vec<O>, and formats each item with Template<C>. It cannot be cleanly turned into a function of (&C) -> Vec<Template<()>> type. So list-like methods are implemented on Box<dyn ListTemplate<C>> instead.
This commit is contained in:
parent
ec5dd96e66
commit
2fbe581a71
1 changed files with 43 additions and 0 deletions
|
@ -25,6 +25,20 @@ pub trait Template<C> {
|
||||||
fn format(&self, context: &C, formatter: &mut dyn Formatter) -> io::Result<()>;
|
fn format(&self, context: &C, formatter: &mut dyn Formatter) -> io::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Template that supports list-like behavior.
|
||||||
|
pub trait ListTemplate<C>: Template<C> {
|
||||||
|
/// Concatenates items with the given separator.
|
||||||
|
fn join<'a>(self: Box<Self>, separator: Box<dyn Template<C> + 'a>) -> Box<dyn Template<C> + 'a>
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
C: 'a;
|
||||||
|
|
||||||
|
/// Upcasts to the template type.
|
||||||
|
fn into_template<'a>(self: Box<Self>) -> Box<dyn Template<C> + 'a>
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
}
|
||||||
|
|
||||||
pub trait IntoTemplate<'a, C> {
|
pub trait IntoTemplate<'a, C> {
|
||||||
fn into_template(self) -> Box<dyn Template<C> + 'a>;
|
fn into_template(self) -> Box<dyn Template<C> + 'a>;
|
||||||
}
|
}
|
||||||
|
@ -413,6 +427,35 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<C, O, P, S, F> ListTemplate<C> for ListPropertyTemplate<P, S, F>
|
||||||
|
where
|
||||||
|
P: TemplateProperty<C>,
|
||||||
|
P::Output: IntoIterator<Item = O>,
|
||||||
|
S: Template<C>,
|
||||||
|
F: Fn(&C, &mut dyn Formatter, O) -> io::Result<()>,
|
||||||
|
{
|
||||||
|
fn join<'a>(self: Box<Self>, separator: Box<dyn Template<C> + 'a>) -> Box<dyn Template<C> + '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<Self>) -> Box<dyn Template<C> + 'a>
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
{
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ConditionalTemplate<P, T, U> {
|
pub struct ConditionalTemplate<P, T, U> {
|
||||||
pub condition: P,
|
pub condition: P,
|
||||||
pub true_template: T,
|
pub true_template: T,
|
||||||
|
|
Loading…
Reference in a new issue