templater: implement string.contains() method as example

This commit is contained in:
Yuya Nishihara 2023-02-04 16:38:39 +09:00
parent 54de6168f2
commit 5342d2cfb7
2 changed files with 29 additions and 1 deletions

View file

@ -399,9 +399,21 @@ fn parse_string_method<'a, I: 'a>(
self_property: impl TemplateProperty<I, Output = String> + 'a,
name: Pair<Rule>,
args_pair: Pair<Rule>,
_parse_keyword: &impl Fn(Pair<Rule>) -> TemplateParseResult<PropertyAndLabels<'a, I>>,
parse_keyword: &impl Fn(Pair<Rule>) -> TemplateParseResult<PropertyAndLabels<'a, I>>,
) -> TemplateParseResult<Property<'a, I>> {
let property = match name.as_str() {
"contains" => {
let [needle_pair] = expect_exact_arguments(args_pair)?;
// TODO: or .try_into_string() to disable implicit type cast?
let needle_property =
parse_template_rule(needle_pair, parse_keyword)?.into_plain_text();
Property::Boolean(chain_properties(
(self_property, needle_property),
TemplatePropertyFn(|(haystack, needle): &(String, String)| {
haystack.contains(needle)
}),
))
}
"first_line" => {
expect_no_arguments(args_pair)?;
Property::String(chain_properties(

View file

@ -148,6 +148,15 @@ fn test_templater_parse_error() {
= Method "foo" doesn't exist for type "String"
"###);
insta::assert_snapshot!(render_err(r#"description.contains()"#), @r###"
Error: Failed to parse template: --> 1:22
|
1 | description.contains()
| ^
|
= Expected 1 arguments
"###);
insta::assert_snapshot!(render_err(r#"description.first_line("foo")"#), @r###"
Error: Failed to parse template: --> 1:24
|
@ -206,8 +215,15 @@ fn test_templater_string_method() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]);
let repo_path = test_env.env_root().join("repo");
test_env.jj_cmd_success(&repo_path, &["commit", "-m=description 1"]);
let render = |template| get_template_output(&test_env, &repo_path, "@-", template);
insta::assert_snapshot!(render(r#""fooo".contains("foo")"#), @"true");
insta::assert_snapshot!(render(r#""foo".contains("fooo")"#), @"false");
insta::assert_snapshot!(render(r#"description.contains("description")"#), @"true");
insta::assert_snapshot!(
render(r#""description 123".contains(description.first_line())"#), @"true");
insta::assert_snapshot!(render(r#""".first_line()"#), @"");
insta::assert_snapshot!(render(r#""foo\nbar".first_line()"#), @"foo");
}