ok/jj
1
0
Fork 0
forked from mirrors/jj

templater: add string.lines() method

This wouldn't be used much in practice, but is useful for writing tests of
list methods.
This commit is contained in:
Yuya Nishihara 2023-03-07 18:19:50 +09:00
parent f8f24399f2
commit 6c146de2e8
4 changed files with 27 additions and 0 deletions

View file

@ -119,6 +119,7 @@ defined.
* `.contains(needle: Template) -> Boolean`
* `.first_line() -> String`
* `.lines() -> List<String>`: Split into lines excluding newline characters.
* `.upper() -> String`
* `.lower() -> String`

View file

@ -596,6 +596,10 @@ pub trait TemplateLanguage<'a> {
&self,
property: impl TemplateProperty<Self::Context, Output = String> + 'a,
) -> Self::Property;
fn wrap_string_list(
&self,
property: impl TemplateProperty<Self::Context, Output = Vec<String>> + 'a,
) -> Self::Property;
fn wrap_boolean(
&self,
property: impl TemplateProperty<Self::Context, Output = bool> + 'a,
@ -638,6 +642,7 @@ macro_rules! impl_core_wrap_property_fns {
$crate::template_parser::impl_wrap_property_fns!(
$a, $crate::template_parser::CoreTemplatePropertyKind, $outer, {
wrap_string(String) => String,
wrap_string_list(Vec<String>) => StringList,
wrap_boolean(bool) => Boolean,
wrap_integer(i64) => Integer,
wrap_signature(jujutsu_lib::backend::Signature) => Signature,
@ -682,6 +687,7 @@ pub trait IntoTemplateProperty<'a, C>: IntoTemplate<'a, C> {
pub enum CoreTemplatePropertyKind<'a, I> {
String(Box<dyn TemplateProperty<I, Output = String> + 'a>),
StringList(Box<dyn TemplateProperty<I, Output = Vec<String>> + 'a>),
Boolean(Box<dyn TemplateProperty<I, Output = bool> + 'a>),
Integer(Box<dyn TemplateProperty<I, Output = i64> + 'a>),
Signature(Box<dyn TemplateProperty<I, Output = Signature> + 'a>),
@ -700,6 +706,7 @@ impl<'a, I: 'a> IntoTemplateProperty<'a, I> for CoreTemplatePropertyKind<'a, I>
CoreTemplatePropertyKind::String(property) => {
Some(Box::new(TemplateFunction::new(property, |s| !s.is_empty())))
}
// TODO: should we allow implicit cast of List type?
CoreTemplatePropertyKind::Boolean(property) => Some(property),
_ => None,
}
@ -724,6 +731,7 @@ impl<'a, I: 'a> IntoTemplate<'a, I> for CoreTemplatePropertyKind<'a, I> {
fn into_template(self) -> Box<dyn Template<I> + 'a> {
match self {
CoreTemplatePropertyKind::String(property) => property.into_template(),
CoreTemplatePropertyKind::StringList(property) => property.into_template(),
CoreTemplatePropertyKind::Boolean(property) => property.into_template(),
CoreTemplatePropertyKind::Integer(property) => property.into_template(),
CoreTemplatePropertyKind::Signature(property) => property.into_template(),
@ -873,6 +881,9 @@ pub fn build_core_method<'a, L: TemplateLanguage<'a>>(
CoreTemplatePropertyKind::String(property) => {
build_string_method(language, property, function)
}
CoreTemplatePropertyKind::StringList(property) => {
build_list_method(language, property, function)
}
CoreTemplatePropertyKind::Boolean(property) => {
build_boolean_method(language, property, function)
}
@ -915,6 +926,12 @@ fn build_string_method<'a, L: TemplateLanguage<'a>>(
s.lines().next().unwrap_or_default().to_string()
}))
}
"lines" => {
expect_no_arguments(function)?;
language.wrap_string_list(TemplateFunction::new(self_property, |s| {
s.lines().map(|l| l.to_owned()).collect()
}))
}
"upper" => {
expect_no_arguments(function)?;
language.wrap_string(TemplateFunction::new(self_property, |s| s.to_uppercase()))

View file

@ -97,6 +97,12 @@ impl Template<()> for TimestampRange {
}
}
impl Template<()> for Vec<String> {
fn format(&self, _: &(), formatter: &mut dyn Formatter) -> io::Result<()> {
format_joined(&(), formatter, self, " ")
}
}
impl Template<()> for bool {
fn format(&self, _: &(), formatter: &mut dyn Formatter) -> io::Result<()> {
formatter.write_str(if *self { "true" } else { "false" })

View file

@ -252,6 +252,9 @@ fn test_templater_string_method() {
insta::assert_snapshot!(render(r#""".first_line()"#), @"");
insta::assert_snapshot!(render(r#""foo\nbar".first_line()"#), @"foo");
insta::assert_snapshot!(render(r#""".lines()"#), @"");
insta::assert_snapshot!(render(r#""a\nb\nc\n".lines()"#), @"a b c");
}
#[test]