forked from mirrors/jj
templater: add string.len() and list.len() methods
This commit is contained in:
parent
0656409904
commit
82b3017fda
3 changed files with 32 additions and 5 deletions
|
@ -488,6 +488,11 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a>>() -> TemplateBuildMethodF
|
||||||
// Not using maplit::hashmap!{} or custom declarative macro here because
|
// Not using maplit::hashmap!{} or custom declarative macro here because
|
||||||
// code completion inside macro is quite restricted.
|
// code completion inside macro is quite restricted.
|
||||||
let mut map = TemplateBuildMethodFnMap::<L, String>::new();
|
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(
|
map.insert(
|
||||||
"contains",
|
"contains",
|
||||||
|language, build_ctx, self_property, function| {
|
|language, build_ctx, self_property, function| {
|
||||||
|
@ -762,6 +767,12 @@ where
|
||||||
O: Template<()> + Clone + 'a,
|
O: Template<()> + Clone + 'a,
|
||||||
{
|
{
|
||||||
let property = match function.name {
|
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" => {
|
"join" => {
|
||||||
let [separator_node] = template_parser::expect_exact_arguments(function)?;
|
let [separator_node] = template_parser::expect_exact_arguments(function)?;
|
||||||
let separator = expect_template_expression(language, build_ctx, separator_node)?;
|
let separator = expect_template_expression(language, build_ctx, separator_node)?;
|
||||||
|
@ -789,6 +800,12 @@ where
|
||||||
O: Clone + 'a,
|
O: Clone + 'a,
|
||||||
{
|
{
|
||||||
let property = match function.name {
|
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"
|
// No "join"
|
||||||
"map" => build_map_operation(language, build_ctx, self_property, function, wrap_item)?,
|
"map" => build_map_operation(language, build_ctx, self_property, function, wrap_item)?,
|
||||||
_ => return Err(TemplateParseError::no_such_method("List", function)),
|
_ => return Err(TemplateParseError::no_such_method("List", function)),
|
||||||
|
@ -1536,6 +1553,9 @@ mod tests {
|
||||||
language.wrap_string(Literal("sep".to_owned()))
|
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#""".lines().join("|")"#), @"");
|
||||||
insta::assert_snapshot!(env.render_ok(r#""a\nb\nc".lines().join("|")"#), @"a|b|c");
|
insta::assert_snapshot!(env.render_ok(r#""a\nb\nc".lines().join("|")"#), @"a|b|c");
|
||||||
// Null separator
|
// Null separator
|
||||||
|
@ -1633,6 +1653,10 @@ mod tests {
|
||||||
language.wrap_string(Literal("description 1".to_owned()))
|
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#""fooo".contains("foo")"#), @"true");
|
||||||
insta::assert_snapshot!(env.render_ok(r#""foo".contains("fooo")"#), @"false");
|
insta::assert_snapshot!(env.render_ok(r#""foo".contains("fooo")"#), @"false");
|
||||||
insta::assert_snapshot!(env.render_ok(r#"description.contains("description")"#), @"true");
|
insta::assert_snapshot!(env.render_ok(r#"description.contains("description")"#), @"true");
|
||||||
|
|
|
@ -26,17 +26,18 @@ fn test_log_parents() {
|
||||||
test_env.jj_cmd_ok(&repo_path, &["new", "@-"]);
|
test_env.jj_cmd_ok(&repo_path, &["new", "@-"]);
|
||||||
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]);
|
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", template]);
|
||||||
insta::assert_snapshot!(stdout, @r###"
|
insta::assert_snapshot!(stdout, @r###"
|
||||||
@ c067170d4ca1bc6162b64f7550617ec809647f84
|
@ c067170d4ca1bc6162b64f7550617ec809647f84
|
||||||
├─╮ P: 4db490c88528133d579540b6900b8098f0c17701 230dd059e1b059aefc0da06a2e5a7dbf22362f22
|
├─╮ P: 2 4db490c88528133d579540b6900b8098f0c17701 230dd059e1b059aefc0da06a2e5a7dbf22362f22
|
||||||
◉ │ 4db490c88528133d579540b6900b8098f0c17701
|
◉ │ 4db490c88528133d579540b6900b8098f0c17701
|
||||||
├─╯ P: 230dd059e1b059aefc0da06a2e5a7dbf22362f22
|
├─╯ P: 1 230dd059e1b059aefc0da06a2e5a7dbf22362f22
|
||||||
◉ 230dd059e1b059aefc0da06a2e5a7dbf22362f22
|
◉ 230dd059e1b059aefc0da06a2e5a7dbf22362f22
|
||||||
│ P: 0000000000000000000000000000000000000000
|
│ P: 1 0000000000000000000000000000000000000000
|
||||||
◉ 0000000000000000000000000000000000000000
|
◉ 0000000000000000000000000000000000000000
|
||||||
P:
|
P: 0
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
let template = r#"parents.map(|c| c.commit_id().shortest(4))"#;
|
let template = r#"parents.map(|c| c.commit_id().shortest(4))"#;
|
||||||
|
|
|
@ -105,6 +105,7 @@ No methods are defined.
|
||||||
A list can be implicitly converted to `Boolean`. The following methods are
|
A list can be implicitly converted to `Boolean`. The following methods are
|
||||||
defined.
|
defined.
|
||||||
|
|
||||||
|
* `.len() -> Integer`: Number of elements in the list.
|
||||||
* `.join(separator: Template) -> Template`: Concatenate elements with
|
* `.join(separator: Template) -> Template`: Concatenate elements with
|
||||||
the given `separator`.
|
the given `separator`.
|
||||||
* `.map(|item| expression) -> ListTemplate`: Apply template `expression`
|
* `.map(|item| expression) -> ListTemplate`: Apply template `expression`
|
||||||
|
@ -164,6 +165,7 @@ The following methods are defined.
|
||||||
A string can be implicitly converted to `Boolean`. The following methods are
|
A string can be implicitly converted to `Boolean`. The following methods are
|
||||||
defined.
|
defined.
|
||||||
|
|
||||||
|
* `.len() -> Integer`: Length in UTF-8 bytes.
|
||||||
* `.contains(needle: Template) -> Boolean`
|
* `.contains(needle: Template) -> Boolean`
|
||||||
* `.first_line() -> String`
|
* `.first_line() -> String`
|
||||||
* `.lines() -> List<String>`: Split into lines excluding newline characters.
|
* `.lines() -> List<String>`: Split into lines excluding newline characters.
|
||||||
|
|
Loading…
Reference in a new issue