Skip to content

Commit

Permalink
templater: add string.len() and list.len() methods
Browse files Browse the repository at this point in the history
  • Loading branch information
yuja committed Feb 29, 2024
1 parent d7ac649 commit fcb8502
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
24 changes: 24 additions & 0 deletions cli/src/template_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,11 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a>>() -> TemplateBuildMethodF
// Not using maplit::hashmap!{} or custom declarative macro here because
// code completion inside macro is quite restricted.
let mut map = TemplateBuildMethodFnMap::<L, String>::new();
map.insert("len", |language, _build_ctx, self_property, function| {
template_parser::expect_no_arguments(function)?;
let out_property = TemplateFunction::new(self_property, |s| Ok(s.len().try_into()?));
Ok(language.wrap_integer(out_property))
});
map.insert(
"contains",
|language, build_ctx, self_property, function| {
Expand Down Expand Up @@ -762,6 +767,12 @@ where
O: Template<()> + Clone + 'a,
{
let property = match function.name {
"len" => {
template_parser::expect_no_arguments(function)?;
let out_property =
TemplateFunction::new(self_property, |items| Ok(items.len().try_into()?));
language.wrap_integer(out_property)
}
"join" => {
let [separator_node] = template_parser::expect_exact_arguments(function)?;
let separator = expect_template_expression(language, build_ctx, separator_node)?;
Expand Down Expand Up @@ -789,6 +800,12 @@ where
O: Clone + 'a,
{
let property = match function.name {
"len" => {
template_parser::expect_no_arguments(function)?;
let out_property =
TemplateFunction::new(self_property, |items| Ok(items.len().try_into()?));
language.wrap_integer(out_property)
}
// No "join"
"map" => build_map_operation(language, build_ctx, self_property, function, wrap_item)?,
_ => return Err(TemplateParseError::no_such_method("List", function)),
Expand Down Expand Up @@ -1536,6 +1553,9 @@ mod tests {
language.wrap_string(Literal("sep".to_owned()))
});

insta::assert_snapshot!(env.render_ok(r#""".lines().len()"#), @"0");
insta::assert_snapshot!(env.render_ok(r#""a\nb\nc".lines().len()"#), @"3");

insta::assert_snapshot!(env.render_ok(r#""".lines().join("|")"#), @"");
insta::assert_snapshot!(env.render_ok(r#""a\nb\nc".lines().join("|")"#), @"a|b|c");
// Null separator
Expand Down Expand Up @@ -1633,6 +1653,10 @@ mod tests {
language.wrap_string(Literal("description 1".to_owned()))
});

insta::assert_snapshot!(env.render_ok(r#""".len()"#), @"0");
insta::assert_snapshot!(env.render_ok(r#""foo".len()"#), @"3");
insta::assert_snapshot!(env.render_ok(r#""💩".len()"#), @"4");

insta::assert_snapshot!(env.render_ok(r#""fooo".contains("foo")"#), @"true");
insta::assert_snapshot!(env.render_ok(r#""foo".contains("fooo")"#), @"false");
insta::assert_snapshot!(env.render_ok(r#"description.contains("description")"#), @"true");
Expand Down
11 changes: 6 additions & 5 deletions cli/tests/test_commit_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@ fn test_log_parents() {
test_env.jj_cmd_ok(&repo_path, &["new", "@-"]);
test_env.jj_cmd_ok(&repo_path, &["new", "@", "@-"]);

let template = r#"commit_id ++ "\nP: " ++ parents.map(|c| c.commit_id()) ++ "\n""#;
let template =
r#"commit_id ++ "\nP: " ++ parents.len() ++ " " ++ parents.map(|c| c.commit_id()) ++ "\n""#;
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", template]);
insta::assert_snapshot!(stdout, @r###"
@ c067170d4ca1bc6162b64f7550617ec809647f84
├─╮ P: 4db490c88528133d579540b6900b8098f0c17701 230dd059e1b059aefc0da06a2e5a7dbf22362f22
├─╮ P: 2 4db490c88528133d579540b6900b8098f0c17701 230dd059e1b059aefc0da06a2e5a7dbf22362f22
◉ │ 4db490c88528133d579540b6900b8098f0c17701
├─╯ P: 230dd059e1b059aefc0da06a2e5a7dbf22362f22
├─╯ P: 1 230dd059e1b059aefc0da06a2e5a7dbf22362f22
◉ 230dd059e1b059aefc0da06a2e5a7dbf22362f22
│ P: 0000000000000000000000000000000000000000
│ P: 1 0000000000000000000000000000000000000000
◉ 0000000000000000000000000000000000000000
P:
P: 0
"###);

let template = r#"parents.map(|c| c.commit_id().shortest(4))"#;
Expand Down
2 changes: 2 additions & 0 deletions docs/templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ No methods are defined.
A list can be implicitly converted to `Boolean`. The following methods are
defined.

* `.len() -> Integer`: Number of elements in the list.
* `.join(separator: Template) -> Template`: Concatenate elements with
the given `separator`.
* `.map(|item| expression) -> ListTemplate`: Apply template `expression`
Expand Down Expand Up @@ -164,6 +165,7 @@ The following methods are defined.
A string can be implicitly converted to `Boolean`. The following methods are
defined.

* `.len() -> Integer`: Length in UTF-8 bytes.
* `.contains(needle: Template) -> Boolean`
* `.first_line() -> String`
* `.lines() -> List<String>`: Split into lines excluding newline characters.
Expand Down

0 comments on commit fcb8502

Please sign in to comment.