diff --git a/cli/examples/custom-commit-templater/main.rs b/cli/examples/custom-commit-templater/main.rs index 6c408c894..bf1c0c342 100644 --- a/cli/examples/custom-commit-templater/main.rs +++ b/cli/examples/custom-commit-templater/main.rs @@ -131,18 +131,17 @@ impl CommitTemplateLanguageExtension for HexCounter { .cache_extension::() .unwrap() .count(language.repo()); - Ok(L::wrap_boolean(property.map(move |commit| { - num_digits_in_id(commit.id()) == most_digits - }))) + let out_property = + property.map(move |commit| num_digits_in_id(commit.id()) == most_digits); + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); table.commit_methods.insert( "num_digits_in_id", |_language, _diagnostics, _build_context, property, call| { call.expect_no_arguments()?; - Ok(L::wrap_integer( - property.map(|commit| num_digits_in_id(commit.id())), - )) + let out_property = property.map(|commit| num_digits_in_id(commit.id())); + Ok(L::wrap_integer(out_property.into_dyn())) }, ); table.commit_methods.insert( @@ -161,9 +160,8 @@ impl CommitTemplateLanguageExtension for HexCounter { } })?; - Ok(L::wrap_integer( - property.map(move |commit| num_char_in_id(commit, char_arg)), - )) + let out_property = property.map(move |commit| num_char_in_id(commit, char_arg)); + Ok(L::wrap_integer(out_property.into_dyn())) }, ); diff --git a/cli/examples/custom-operation-templater/main.rs b/cli/examples/custom-operation-templater/main.rs index ac57ee612..0608568c0 100644 --- a/cli/examples/custom-operation-templater/main.rs +++ b/cli/examples/custom-operation-templater/main.rs @@ -55,9 +55,8 @@ impl OperationTemplateLanguageExtension for HexCounter { "num_digits_in_id", |_language, _diagnostics, _build_context, property, call| { call.expect_no_arguments()?; - Ok(L::wrap_integer( - property.map(|operation| num_digits_in_id(operation.id())), - )) + let out_property = property.map(|operation| num_digits_in_id(operation.id())); + Ok(L::wrap_integer(out_property.into_dyn())) }, ); table.operation_methods.insert( @@ -76,9 +75,9 @@ impl OperationTemplateLanguageExtension for HexCounter { } })?; - Ok(L::wrap_integer( - property.map(move |operation| num_char_in_id(operation, char_arg)), - )) + let out_property = + property.map(move |operation| num_char_in_id(operation, char_arg)); + Ok(L::wrap_integer(out_property.into_dyn())) }, ); diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index 03c836221..23b8b5b08 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -177,7 +177,7 @@ use crate::template_builder; use crate::template_builder::TemplateLanguage; use crate::template_parser::TemplateAliasesMap; use crate::template_parser::TemplateDiagnostics; -use crate::templater::PropertyPlaceholder; +use crate::templater::TemplateProperty; use crate::templater::TemplateRenderer; use crate::text_util; use crate::ui::ColorChoice; @@ -386,7 +386,7 @@ impl CommandHelper { ui: &Ui, language: &L, template_text: &str, - wrap_self: impl Fn(PropertyPlaceholder) -> L::Property, + wrap_self: impl Fn(Box + 'a>) -> L::Property, ) -> Result, CommandError> { let mut diagnostics = TemplateDiagnostics::new(); let aliases = load_template_aliases(ui, self.settings().config())?; @@ -974,7 +974,7 @@ impl WorkspaceCommandEnvironment { ui: &Ui, language: &L, template_text: &str, - wrap_self: impl Fn(PropertyPlaceholder) -> L::Property, + wrap_self: impl Fn(Box + 'a>) -> L::Property, ) -> Result, CommandError> { let mut diagnostics = TemplateDiagnostics::new(); let template = template_builder::parse( @@ -1704,7 +1704,7 @@ to the current parents may contain changes from multiple commits. ui: &Ui, language: &L, template_text: &str, - wrap_self: impl Fn(PropertyPlaceholder) -> L::Property, + wrap_self: impl Fn(Box + 'a>) -> L::Property, ) -> Result, CommandError> { self.env .parse_template(ui, language, template_text, wrap_self) @@ -1715,7 +1715,7 @@ to the current parents may contain changes from multiple commits. &self, language: &L, template_text: &str, - wrap_self: impl Fn(PropertyPlaceholder) -> L::Property, + wrap_self: impl Fn(Box + 'a>) -> L::Property, ) -> TemplateRenderer<'a, C> { template_builder::parse( language, diff --git a/cli/src/commands/config/list.rs b/cli/src/commands/config/list.rs index 2b5ebe448..99270712e 100644 --- a/cli/src/commands/config/list.rs +++ b/cli/src/commands/config/list.rs @@ -127,16 +127,16 @@ fn config_template_language( let mut language = L::new(settings); language.add_keyword("name", |self_property| { let out_property = self_property.map(|annotated| annotated.name.to_string()); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }); language.add_keyword("value", |self_property| { // .decorated("", "") to trim leading/trailing whitespace let out_property = self_property.map(|annotated| annotated.value.decorated("", "")); - Ok(L::wrap_config_value(out_property)) + Ok(L::wrap_config_value(out_property.into_dyn())) }); language.add_keyword("source", |self_property| { let out_property = self_property.map(|annotated| annotated.source.to_string()); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }); language.add_keyword("path", |self_property| { let out_property = self_property.map(|annotated| { @@ -146,11 +146,11 @@ fn config_template_language( .as_ref() .map_or_else(String::new, |path| path.to_string_lossy().into_owned()) }); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }); language.add_keyword("overridden", |self_property| { let out_property = self_property.map(|annotated| annotated.is_overridden); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }); language } diff --git a/cli/src/commit_templater.rs b/cli/src/commit_templater.rs index 18ebb7cd4..9ab0b340c 100644 --- a/cli/src/commit_templater.rs +++ b/cli/src/commit_templater.rs @@ -324,7 +324,7 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> { expect_plain_text_expression(self, diagnostics, build_ctx, key_node)?; let out_property = (property, key_property) .map(|(trailers, key)| trailers.iter().any(|t| t.key == key)); - Ok(Self::wrap_boolean(out_property)) + Ok(Self::wrap_boolean(out_property.into_dyn())) } else { template_builder::build_formattable_list_method( self, @@ -361,117 +361,117 @@ impl<'repo> CommitTemplateLanguage<'repo> { } pub fn wrap_commit( - property: impl TemplateProperty + 'repo, + property: Box + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::Commit(Box::new(property)) + CommitTemplatePropertyKind::Commit(property) } pub fn wrap_commit_opt( - property: impl TemplateProperty> + 'repo, + property: Box> + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::CommitOpt(Box::new(property)) + CommitTemplatePropertyKind::CommitOpt(property) } pub fn wrap_commit_list( - property: impl TemplateProperty> + 'repo, + property: Box> + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::CommitList(Box::new(property)) + CommitTemplatePropertyKind::CommitList(property) } pub fn wrap_commit_ref( - property: impl TemplateProperty> + 'repo, + property: Box> + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::CommitRef(Box::new(property)) + CommitTemplatePropertyKind::CommitRef(property) } pub fn wrap_commit_ref_opt( - property: impl TemplateProperty>> + 'repo, + property: Box>> + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::CommitRefOpt(Box::new(property)) + CommitTemplatePropertyKind::CommitRefOpt(property) } pub fn wrap_commit_ref_list( - property: impl TemplateProperty>> + 'repo, + property: Box>> + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::CommitRefList(Box::new(property)) + CommitTemplatePropertyKind::CommitRefList(property) } pub fn wrap_repo_path( - property: impl TemplateProperty + 'repo, + property: Box + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::RepoPath(Box::new(property)) + CommitTemplatePropertyKind::RepoPath(property) } pub fn wrap_repo_path_opt( - property: impl TemplateProperty> + 'repo, + property: Box> + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::RepoPathOpt(Box::new(property)) + CommitTemplatePropertyKind::RepoPathOpt(property) } pub fn wrap_commit_or_change_id( - property: impl TemplateProperty + 'repo, + property: Box + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::CommitOrChangeId(Box::new(property)) + CommitTemplatePropertyKind::CommitOrChangeId(property) } pub fn wrap_shortest_id_prefix( - property: impl TemplateProperty + 'repo, + property: Box + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::ShortestIdPrefix(Box::new(property)) + CommitTemplatePropertyKind::ShortestIdPrefix(property) } pub fn wrap_tree_diff( - property: impl TemplateProperty + 'repo, + property: Box + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::TreeDiff(Box::new(property)) + CommitTemplatePropertyKind::TreeDiff(property) } pub fn wrap_tree_diff_entry( - property: impl TemplateProperty + 'repo, + property: Box + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::TreeDiffEntry(Box::new(property)) + CommitTemplatePropertyKind::TreeDiffEntry(property) } pub fn wrap_tree_diff_entry_list( - property: impl TemplateProperty> + 'repo, + property: Box> + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::TreeDiffEntryList(Box::new(property)) + CommitTemplatePropertyKind::TreeDiffEntryList(property) } pub fn wrap_tree_entry( - property: impl TemplateProperty + 'repo, + property: Box + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::TreeEntry(Box::new(property)) + CommitTemplatePropertyKind::TreeEntry(property) } pub fn wrap_diff_stats( - property: impl TemplateProperty> + 'repo, + property: Box> + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::DiffStats(Box::new(property)) + CommitTemplatePropertyKind::DiffStats(property) } fn wrap_cryptographic_signature_opt( - property: impl TemplateProperty> + 'repo, + property: Box> + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::CryptographicSignatureOpt(Box::new(property)) + CommitTemplatePropertyKind::CryptographicSignatureOpt(property) } pub fn wrap_annotation_line( - property: impl TemplateProperty + 'repo, + property: Box + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::AnnotationLine(Box::new(property)) + CommitTemplatePropertyKind::AnnotationLine(property) } pub fn wrap_trailer( - property: impl TemplateProperty + 'repo, + property: Box + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::Trailer(Box::new(property)) + CommitTemplatePropertyKind::Trailer(property) } pub fn wrap_trailer_list( - property: impl TemplateProperty> + 'repo, + property: Box> + 'repo>, ) -> CommitTemplatePropertyKind<'repo> { - CommitTemplatePropertyKind::TrailerList(Box::new(property)) + CommitTemplatePropertyKind::TrailerList(property) } } @@ -831,7 +831,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm function.expect_no_arguments()?; let out_property = self_property.map(|commit| text_util::complete_newline(commit.description())); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -840,7 +840,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm function.expect_no_arguments()?; let out_property = self_property .map(|commit| trailer::parse_description_trailers(commit.description())); - Ok(L::wrap_trailer_list(out_property)) + Ok(L::wrap_trailer_list(out_property.into_dyn())) }, ); map.insert( @@ -849,7 +849,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm function.expect_no_arguments()?; let out_property = self_property.map(|commit| CommitOrChangeId::Change(commit.change_id().to_owned())); - Ok(L::wrap_commit_or_change_id(out_property)) + Ok(L::wrap_commit_or_change_id(out_property.into_dyn())) }, ); map.insert( @@ -858,7 +858,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm function.expect_no_arguments()?; let out_property = self_property.map(|commit| CommitOrChangeId::Commit(commit.id().to_owned())); - Ok(L::wrap_commit_or_change_id(out_property)) + Ok(L::wrap_commit_or_change_id(out_property.into_dyn())) }, ); map.insert( @@ -867,7 +867,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm function.expect_no_arguments()?; let out_property = self_property.and_then(|commit| Ok(commit.parents().try_collect()?)); - Ok(L::wrap_commit_list(out_property)) + Ok(L::wrap_commit_list(out_property.into_dyn())) }, ); map.insert( @@ -875,7 +875,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|commit| commit.author().clone()); - Ok(L::wrap_signature(out_property)) + Ok(L::wrap_signature(out_property.into_dyn())) }, ); map.insert( @@ -883,7 +883,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|commit| commit.committer().clone()); - Ok(L::wrap_signature(out_property)) + Ok(L::wrap_signature(out_property.into_dyn())) }, ); map.insert( @@ -892,7 +892,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm function.expect_no_arguments()?; let user_email = language.revset_parse_context.user_email.to_owned(); let out_property = self_property.map(move |commit| commit.author().email == user_email); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -900,7 +900,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(CryptographicSignature::new); - Ok(L::wrap_cryptographic_signature_opt(out_property)) + Ok(L::wrap_cryptographic_signature_opt(out_property.into_dyn())) }, ); map.insert( @@ -909,7 +909,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm function.expect_no_arguments()?; let repo = language.repo; let out_property = self_property.map(|commit| extract_working_copies(repo, &commit)); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -920,7 +920,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm let name = language.workspace_name.clone(); let out_property = self_property .map(move |commit| Some(commit.id()) == repo.view().get_wc_commit_id(&name)); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -939,7 +939,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm .cloned() .collect() }); - Ok(L::wrap_commit_ref_list(out_property)) + Ok(L::wrap_commit_ref_list(out_property.into_dyn())) }, ); map.insert( @@ -958,7 +958,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm .cloned() .collect() }); - Ok(L::wrap_commit_ref_list(out_property)) + Ok(L::wrap_commit_ref_list(out_property.into_dyn())) }, ); map.insert( @@ -977,7 +977,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm .cloned() .collect() }); - Ok(L::wrap_commit_ref_list(out_property)) + Ok(L::wrap_commit_ref_list(out_property.into_dyn())) }, ); map.insert( @@ -986,7 +986,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm function.expect_no_arguments()?; let index = language.keyword_cache.tags_index(language.repo).clone(); let out_property = self_property.map(move |commit| index.get(commit.id()).to_vec()); - Ok(L::wrap_commit_ref_list(out_property)) + Ok(L::wrap_commit_ref_list(out_property.into_dyn())) }, ); map.insert( @@ -995,7 +995,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm function.expect_no_arguments()?; let index = language.keyword_cache.git_refs_index(language.repo).clone(); let out_property = self_property.map(move |commit| index.get(commit.id()).to_vec()); - Ok(L::wrap_commit_ref_list(out_property)) + Ok(L::wrap_commit_ref_list(out_property.into_dyn())) }, ); map.insert( @@ -1007,7 +1007,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm let target = repo.view().git_head(); target.added_ids().contains(commit.id()) }); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -1020,7 +1020,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm let maybe_entries = repo.resolve_change_id(commit.change_id()); maybe_entries.map_or(0, |entries| entries.len()) > 1 }); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -1029,7 +1029,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm function.expect_no_arguments()?; let repo = language.repo; let out_property = self_property.map(|commit| commit.is_hidden(repo)); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -1041,7 +1041,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm .is_immutable_fn(language, function.name_span)? .clone(); let out_property = self_property.and_then(move |commit| Ok(is_immutable(commit.id())?)); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -1055,7 +1055,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm })?; let out_property = self_property.and_then(move |commit| Ok(is_contained(commit.id())?)); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -1063,7 +1063,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.and_then(|commit| Ok(commit.has_conflict()?)); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -1072,7 +1072,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm function.expect_no_arguments()?; let repo = language.repo; let out_property = self_property.and_then(|commit| Ok(commit.is_empty(repo)?)); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -1090,7 +1090,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm let matcher: Rc = files.to_matcher().into(); let out_property = self_property .and_then(move |commit| Ok(TreeDiff::from_commit(repo, &commit, matcher.clone())?)); - Ok(L::wrap_tree_diff(out_property)) + Ok(L::wrap_tree_diff(out_property.into_dyn())) }, ); map.insert( @@ -1100,7 +1100,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm let repo = language.repo; let out_property = self_property.map(|commit| commit.id() == repo.store().root_commit_id()); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map @@ -1399,7 +1399,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|commit_ref| commit_ref.name.clone()); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -1408,7 +1408,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, function.expect_no_arguments()?; let out_property = self_property.map(|commit_ref| commit_ref.remote.clone().unwrap_or_default()); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -1416,7 +1416,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|commit_ref| commit_ref.is_present()); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -1424,7 +1424,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|commit_ref| commit_ref.has_conflict()); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -1436,7 +1436,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, let maybe_id = commit_ref.target.as_normal(); Ok(maybe_id.map(|id| repo.store().get_commit(id)).transpose()?) }); - Ok(L::wrap_commit_opt(out_property)) + Ok(L::wrap_commit_opt(out_property.into_dyn())) }, ); map.insert( @@ -1448,7 +1448,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, let ids = commit_ref.target.removed_ids(); Ok(ids.map(|id| repo.store().get_commit(id)).try_collect()?) }); - Ok(L::wrap_commit_list(out_property)) + Ok(L::wrap_commit_list(out_property.into_dyn())) }, ); map.insert( @@ -1460,7 +1460,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, let ids = commit_ref.target.added_ids(); Ok(ids.map(|id| repo.store().get_commit(id)).try_collect()?) }); - Ok(L::wrap_commit_list(out_property)) + Ok(L::wrap_commit_list(out_property.into_dyn())) }, ); map.insert( @@ -1468,7 +1468,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|commit_ref| commit_ref.is_tracked()); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -1476,7 +1476,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|commit_ref| commit_ref.is_tracking_present()); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -1486,7 +1486,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, let repo = language.repo; let out_property = self_property.and_then(|commit_ref| commit_ref.tracking_ahead_count(repo)); - Ok(L::wrap_size_hint(out_property)) + Ok(L::wrap_size_hint(out_property.into_dyn())) }, ); map.insert( @@ -1496,7 +1496,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, let repo = language.repo; let out_property = self_property.and_then(|commit_ref| commit_ref.tracking_behind_count(repo)); - Ok(L::wrap_size_hint(out_property)) + Ok(L::wrap_size_hint(out_property.into_dyn())) }, ); map @@ -1571,7 +1571,7 @@ fn builtin_repo_path_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, R function.expect_no_arguments()?; let path_converter = language.path_converter; let out_property = self_property.map(|path| path_converter.format_file_path(&path)); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -1579,7 +1579,7 @@ fn builtin_repo_path_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, R |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|path| Some(path.parent()?.to_owned())); - Ok(L::wrap_repo_path_opt(out_property)) + Ok(L::wrap_repo_path_opt(out_property.into_dyn())) }, ); map @@ -1640,7 +1640,7 @@ fn builtin_commit_or_change_id_methods<'repo>( "normal_hex", |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; - Ok(L::wrap_string(self_property.map(|id| { + let out_property = self_property.map(|id| { // Note: this is _not_ the same as id.hex() for ChangeId, which // returns the "reverse" hex (z-k), instead of the "forward" / // normal hex (0-9a-f) we want here. @@ -1648,7 +1648,8 @@ fn builtin_commit_or_change_id_methods<'repo>( CommitOrChangeId::Commit(id) => id.hex(), CommitOrChangeId::Change(id) => id.hex(), } - }))) + }); + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -1667,7 +1668,7 @@ fn builtin_commit_or_change_id_methods<'repo>( .transpose()?; let out_property = (self_property, len_property).map(|(id, len)| id.short(len.unwrap_or(12))); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -1702,7 +1703,7 @@ fn builtin_commit_or_change_id_methods<'repo>( }; let out_property = (self_property, len_property) .map(move |(id, len)| id.shortest(repo, &index, len.unwrap_or(0))); - Ok(L::wrap_shortest_id_prefix(out_property)) + Ok(L::wrap_shortest_id_prefix(out_property.into_dyn())) }, ); map @@ -1747,7 +1748,7 @@ fn builtin_shortest_id_prefix_methods<'repo>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|id| id.prefix); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -1755,7 +1756,7 @@ fn builtin_shortest_id_prefix_methods<'repo>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|id| id.rest); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -1763,7 +1764,7 @@ fn builtin_shortest_id_prefix_methods<'repo>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|id| id.to_upper()); - Ok(L::wrap_shortest_id_prefix(out_property)) + Ok(L::wrap_shortest_id_prefix(out_property.into_dyn())) }, ); map.insert( @@ -1771,7 +1772,7 @@ fn builtin_shortest_id_prefix_methods<'repo>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|id| id.to_lower()); - Ok(L::wrap_shortest_id_prefix(out_property)) + Ok(L::wrap_shortest_id_prefix(out_property.into_dyn())) }, ); map @@ -1858,7 +1859,7 @@ fn builtin_tree_diff_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, T // TODO: cache and reuse diff entries within the current evaluation? let out_property = self_property.and_then(|diff| Ok(diff.collect_entries().block_on()?)); - Ok(L::wrap_tree_diff_entry_list(out_property)) + Ok(L::wrap_tree_diff_entry_list(out_property.into_dyn())) }, ); map.insert( @@ -1974,7 +1975,7 @@ fn builtin_tree_diff_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, T width: width.unwrap_or(80), }) }); - Ok(L::wrap_diff_stats(out_property)) + Ok(L::wrap_diff_stats(out_property.into_dyn())) }, ); map.insert( @@ -2049,7 +2050,7 @@ fn builtin_tree_diff_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'r |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|entry| entry.path.target); - Ok(L::wrap_repo_path(out_property)) + Ok(L::wrap_repo_path(out_property.into_dyn())) }, ); map.insert( @@ -2057,7 +2058,7 @@ fn builtin_tree_diff_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'r |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|entry| entry.status_label().to_owned()); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); // TODO: add status_code() or status_char()? @@ -2066,7 +2067,7 @@ fn builtin_tree_diff_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'r |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(TreeDiffEntry::into_source_entry); - Ok(L::wrap_tree_entry(out_property)) + Ok(L::wrap_tree_entry(out_property.into_dyn())) }, ); map.insert( @@ -2074,7 +2075,7 @@ fn builtin_tree_diff_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'r |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(TreeDiffEntry::into_target_entry); - Ok(L::wrap_tree_entry(out_property)) + Ok(L::wrap_tree_entry(out_property.into_dyn())) }, ); map @@ -2097,7 +2098,7 @@ fn builtin_tree_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|entry| entry.path); - Ok(L::wrap_repo_path(out_property)) + Ok(L::wrap_repo_path(out_property.into_dyn())) }, ); map.insert( @@ -2105,7 +2106,7 @@ fn builtin_tree_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|entry| !entry.value.is_resolved()); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -2114,7 +2115,7 @@ fn builtin_tree_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, function.expect_no_arguments()?; let out_property = self_property.map(|entry| describe_file_type(&entry.value).to_owned()); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -2123,7 +2124,7 @@ fn builtin_tree_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, function.expect_no_arguments()?; let out_property = self_property.map(|entry| is_executable_file(&entry.value).unwrap_or_default()); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map @@ -2176,7 +2177,7 @@ fn builtin_diff_stats_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, function.expect_no_arguments()?; let out_property = self_property.and_then(|stats| Ok(stats.count_total_added().try_into()?)); - Ok(L::wrap_integer(out_property)) + Ok(L::wrap_integer(out_property.into_dyn())) }, ); map.insert( @@ -2185,7 +2186,7 @@ fn builtin_diff_stats_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, function.expect_no_arguments()?; let out_property = self_property.and_then(|stats| Ok(stats.count_total_removed().try_into()?)); - Ok(L::wrap_integer(out_property)) + Ok(L::wrap_integer(out_property.into_dyn())) }, ); map @@ -2240,7 +2241,7 @@ fn builtin_cryptographic_signature_methods<'repo>( Err(SignError::InvalidSignatureFormat) => Ok("invalid".to_string()), Err(err) => Err(err.into()), }); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -2248,7 +2249,7 @@ fn builtin_cryptographic_signature_methods<'repo>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.and_then(|sig| Ok(sig.key()?)); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -2256,7 +2257,7 @@ fn builtin_cryptographic_signature_methods<'repo>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.and_then(|sig| Ok(sig.display()?)); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map @@ -2279,7 +2280,7 @@ fn builtin_annotation_line_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'r |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|line| line.commit); - Ok(L::wrap_commit(out_property)) + Ok(L::wrap_commit(out_property.into_dyn())) }, ); map.insert( @@ -2296,7 +2297,7 @@ fn builtin_annotation_line_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'r |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.and_then(|line| Ok(line.line_number.try_into()?)); - Ok(L::wrap_integer(out_property)) + Ok(L::wrap_integer(out_property.into_dyn())) }, ); map.insert( @@ -2304,7 +2305,7 @@ fn builtin_annotation_line_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'r |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|line| line.first_line_in_hunk); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map @@ -2330,7 +2331,7 @@ fn builtin_trailer_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Tra |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|trailer| trailer.key); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -2338,7 +2339,7 @@ fn builtin_trailer_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Tra |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|trailer| trailer.value); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map diff --git a/cli/src/generic_templater.rs b/cli/src/generic_templater.rs index 1ab7a4b0e..d86b6f241 100644 --- a/cli/src/generic_templater.rs +++ b/cli/src/generic_templater.rs @@ -132,9 +132,9 @@ impl<'a, C> TemplateLanguage<'a> for GenericTemplateLanguage<'a, C> { impl<'a, C> GenericTemplateLanguage<'a, C> { pub fn wrap_self( - property: impl TemplateProperty + 'a, + property: Box + 'a>, ) -> GenericTemplatePropertyKind<'a, C> { - GenericTemplatePropertyKind::Self_(Box::new(property)) + GenericTemplatePropertyKind::Self_(property) } } diff --git a/cli/src/operation_templater.rs b/cli/src/operation_templater.rs index 32403286b..13fec53fa 100644 --- a/cli/src/operation_templater.rs +++ b/cli/src/operation_templater.rs @@ -137,15 +137,15 @@ impl OperationTemplateLanguage { } pub fn wrap_operation( - property: impl TemplateProperty + 'static, + property: Box + 'static>, ) -> OperationTemplatePropertyKind { - OperationTemplatePropertyKind::Operation(Box::new(property)) + OperationTemplatePropertyKind::Operation(property) } pub fn wrap_operation_id( - property: impl TemplateProperty + 'static, + property: Box + 'static>, ) -> OperationTemplatePropertyKind { - OperationTemplatePropertyKind::OperationId(Box::new(property)) + OperationTemplatePropertyKind::OperationId(property) } } @@ -275,7 +275,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap { function.expect_no_arguments()?; let current_op_id = language.current_op_id.clone(); let out_property = self_property.map(move |op| Some(op.id()) == current_op_id.as_ref()); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -283,7 +283,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap { |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|op| op.metadata().description.clone()); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -291,7 +291,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap { |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|op| op.id().clone()); - Ok(L::wrap_operation_id(out_property)) + Ok(L::wrap_operation_id(out_property.into_dyn())) }, ); map.insert( @@ -306,7 +306,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap { .map(|(key, value)| format!("{key}: {value}")) .join("\n") }); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -314,7 +314,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap { |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|op| op.metadata().is_snapshot); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -325,7 +325,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap { start: op.metadata().start_time, end: op.metadata().end_time, }); - Ok(L::wrap_timestamp_range(out_property)) + Ok(L::wrap_timestamp_range(out_property.into_dyn())) }, ); map.insert( @@ -336,7 +336,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap { // TODO: introduce dedicated type and provide accessors? format!("{}@{}", op.metadata().username, op.metadata().hostname) }); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -345,7 +345,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap { function.expect_no_arguments()?; let root_op_id = language.repo_loader.op_store().root_operation_id().clone(); let out_property = self_property.map(move |op| op.id() == &root_op_id); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map @@ -381,7 +381,7 @@ fn builtin_operation_id_methods() -> OperationTemplateBuildMethodFnMap { type Property: IntoTemplateProperty<'a>; - fn wrap_string(property: impl TemplateProperty + 'a) -> Self::Property; + fn wrap_string(property: Box + 'a>) -> Self::Property; fn wrap_string_list( - property: impl TemplateProperty> + 'a, + property: Box> + 'a>, ) -> Self::Property; - fn wrap_boolean(property: impl TemplateProperty + 'a) -> Self::Property; - fn wrap_integer(property: impl TemplateProperty + 'a) -> Self::Property; + fn wrap_boolean(property: Box + 'a>) -> Self::Property; + fn wrap_integer(property: Box + 'a>) -> Self::Property; fn wrap_integer_opt( - property: impl TemplateProperty> + 'a, + property: Box> + 'a>, ) -> Self::Property; fn wrap_config_value( - property: impl TemplateProperty + 'a, + property: Box + 'a>, + ) -> Self::Property; + fn wrap_signature( + property: Box + 'a>, + ) -> Self::Property; + fn wrap_email(property: Box + 'a>) -> Self::Property; + fn wrap_size_hint( + property: Box + 'a>, + ) -> Self::Property; + fn wrap_timestamp( + property: Box + 'a>, ) -> Self::Property; - fn wrap_signature(property: impl TemplateProperty + 'a) -> Self::Property; - fn wrap_email(property: impl TemplateProperty + 'a) -> Self::Property; - fn wrap_size_hint(property: impl TemplateProperty + 'a) -> Self::Property; - fn wrap_timestamp(property: impl TemplateProperty + 'a) -> Self::Property; fn wrap_timestamp_range( - property: impl TemplateProperty + 'a, + property: Box + 'a>, ) -> Self::Property; fn wrap_template(template: Box) -> Self::Property; @@ -157,10 +163,10 @@ macro_rules! impl_wrap_property_fns { ($a:lifetime, $kind:path, $outer:path, { $( $func:ident($ty:ty) => $var:ident, )+ }) => { $( fn $func( - property: impl $crate::templater::TemplateProperty + $a, + property: Box + $a>, ) -> Self::Property { use $kind as Kind; // https://github.com/rust-lang/rust/issues/48067 - $outer(Kind::$var(Box::new(property))) + $outer(Kind::$var(property)) } )+ }; @@ -692,14 +698,15 @@ fn build_unary_operation<'a, L: TemplateLanguage<'a> + ?Sized>( match op { UnaryOp::LogicalNot => { let arg = expect_boolean_expression(language, diagnostics, build_ctx, arg_node)?; - Ok(L::wrap_boolean(arg.map(|v| !v))) + Ok(L::wrap_boolean(arg.map(|v| !v).into_dyn())) } UnaryOp::Negate => { let arg = expect_integer_expression(language, diagnostics, build_ctx, arg_node)?; - Ok(L::wrap_integer(arg.and_then(|v| { + let out = arg.and_then(|v| { v.checked_neg() .ok_or_else(|| TemplatePropertyError("Attempt to negate with overflow".into())) - }))) + }); + Ok(L::wrap_integer(out.into_dyn())) } } } @@ -718,45 +725,47 @@ fn build_binary_operation<'a, L: TemplateLanguage<'a> + ?Sized>( let lhs = expect_boolean_expression(language, diagnostics, build_ctx, lhs_node)?; let rhs = expect_boolean_expression(language, diagnostics, build_ctx, rhs_node)?; let out = lhs.and_then(move |l| Ok(l || rhs.extract()?)); - Ok(L::wrap_boolean(out)) + Ok(L::wrap_boolean(out.into_dyn())) } BinaryOp::LogicalAnd => { let lhs = expect_boolean_expression(language, diagnostics, build_ctx, lhs_node)?; let rhs = expect_boolean_expression(language, diagnostics, build_ctx, rhs_node)?; let out = lhs.and_then(move |l| Ok(l && rhs.extract()?)); - Ok(L::wrap_boolean(out)) + Ok(L::wrap_boolean(out.into_dyn())) } BinaryOp::Eq | BinaryOp::Ne => { let lhs = build_expression(language, diagnostics, build_ctx, lhs_node)?; let rhs = build_expression(language, diagnostics, build_ctx, rhs_node)?; let lty = lhs.type_name(); let rty = rhs.type_name(); - let out = lhs.try_into_eq(rhs).ok_or_else(|| { + let eq = lhs.try_into_eq(rhs).ok_or_else(|| { let message = format!("Cannot compare expressions of type `{lty}` and `{rty}`"); TemplateParseError::expression(message, span) })?; - match op { - BinaryOp::Eq => Ok(L::wrap_boolean(out)), - BinaryOp::Ne => Ok(L::wrap_boolean(out.map(|eq| !eq))), + let out = match op { + BinaryOp::Eq => eq.into_dyn(), + BinaryOp::Ne => eq.map(|eq| !eq).into_dyn(), _ => unreachable!(), - } + }; + Ok(L::wrap_boolean(out)) } BinaryOp::Ge | BinaryOp::Gt | BinaryOp::Le | BinaryOp::Lt => { let lhs = build_expression(language, diagnostics, build_ctx, lhs_node)?; let rhs = build_expression(language, diagnostics, build_ctx, rhs_node)?; let lty = lhs.type_name(); let rty = rhs.type_name(); - let out = lhs.try_into_cmp(rhs).ok_or_else(|| { + let cmp = lhs.try_into_cmp(rhs).ok_or_else(|| { let message = format!("Cannot compare expressions of type `{lty}` and `{rty}`"); TemplateParseError::expression(message, span) })?; - match op { - BinaryOp::Ge => Ok(L::wrap_boolean(out.map(|ordering| ordering.is_ge()))), - BinaryOp::Gt => Ok(L::wrap_boolean(out.map(|ordering| ordering.is_gt()))), - BinaryOp::Le => Ok(L::wrap_boolean(out.map(|ordering| ordering.is_le()))), - BinaryOp::Lt => Ok(L::wrap_boolean(out.map(|ordering| ordering.is_lt()))), + let out = match op { + BinaryOp::Ge => cmp.map(|ordering| ordering.is_ge()).into_dyn(), + BinaryOp::Gt => cmp.map(|ordering| ordering.is_gt()).into_dyn(), + BinaryOp::Le => cmp.map(|ordering| ordering.is_le()).into_dyn(), + BinaryOp::Lt => cmp.map(|ordering| ordering.is_lt()).into_dyn(), _ => unreachable!(), - } + }; + Ok(L::wrap_boolean(out)) } } } @@ -771,7 +780,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.and_then(|s| Ok(s.len().try_into()?)); - Ok(L::wrap_integer(out_property)) + Ok(L::wrap_integer(out_property.into_dyn())) }, ); map.insert( @@ -783,7 +792,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( expect_plain_text_expression(language, diagnostics, build_ctx, needle_node)?; let out_property = (self_property, needle_property) .map(|(haystack, needle)| haystack.contains(&needle)); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -794,7 +803,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( expect_plain_text_expression(language, diagnostics, build_ctx, needle_node)?; let out_property = (self_property, needle_property) .map(|(haystack, needle)| haystack.starts_with(&needle)); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -805,7 +814,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( expect_plain_text_expression(language, diagnostics, build_ctx, needle_node)?; let out_property = (self_property, needle_property) .map(|(haystack, needle)| haystack.ends_with(&needle)); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -820,7 +829,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( .map(ToOwned::to_owned) .unwrap_or(haystack) }); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -835,7 +844,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( .map(ToOwned::to_owned) .unwrap_or(haystack) }); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -843,7 +852,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|s| s.trim().to_owned()); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -851,7 +860,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|s| s.trim_start().to_owned()); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -859,7 +868,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|s| s.trim_end().to_owned()); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -877,7 +886,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( s.get(start_idx..end_idx).unwrap_or_default().to_owned() }, ); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -886,7 +895,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( function.expect_no_arguments()?; let out_property = self_property.map(|s| s.lines().next().unwrap_or_default().to_string()); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -894,7 +903,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|s| s.lines().map(|l| l.to_owned()).collect()); - Ok(L::wrap_string_list(out_property)) + Ok(L::wrap_string_list(out_property.into_dyn())) }, ); map.insert( @@ -902,7 +911,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|s| s.to_uppercase()); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -910,7 +919,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|s| s.to_lowercase()); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -918,7 +927,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|s| serde_json::to_string(&s).unwrap()); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map @@ -960,7 +969,7 @@ fn builtin_config_value_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.and_then(extract); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert( @@ -968,7 +977,7 @@ fn builtin_config_value_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.and_then(extract); - Ok(L::wrap_integer(out_property)) + Ok(L::wrap_integer(out_property.into_dyn())) }, ); map.insert( @@ -976,7 +985,7 @@ fn builtin_config_value_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.and_then(extract); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -984,7 +993,7 @@ fn builtin_config_value_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.and_then(extract); - Ok(L::wrap_string_list(out_property)) + Ok(L::wrap_string_list(out_property.into_dyn())) }, ); // TODO: add is_() -> Boolean? @@ -1002,7 +1011,7 @@ fn builtin_signature_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|signature| signature.name); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -1010,7 +1019,7 @@ fn builtin_signature_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|signature| signature.email.into()); - Ok(L::wrap_email(out_property)) + Ok(L::wrap_email(out_property.into_dyn())) }, ); map.insert( @@ -1026,7 +1035,7 @@ fn builtin_signature_methods<'a, L: TemplateLanguage<'a> + ?Sized>( let (username, _) = text_util::split_email(&signature.email); username.to_owned() }); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -1034,7 +1043,7 @@ fn builtin_signature_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|signature| signature.timestamp); - Ok(L::wrap_timestamp(out_property)) + Ok(L::wrap_timestamp(out_property.into_dyn())) }, ); map @@ -1053,7 +1062,7 @@ fn builtin_email_methods<'a, L: TemplateLanguage<'a> + ?Sized>( let (local, _) = text_util::split_email(&email.0); local.to_owned() }); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -1064,7 +1073,7 @@ fn builtin_email_methods<'a, L: TemplateLanguage<'a> + ?Sized>( let (_, domain) = text_util::split_email(&email.0); domain.unwrap_or_default().to_owned() }); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map @@ -1080,7 +1089,7 @@ fn builtin_size_hint_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.and_then(|(lower, _)| Ok(i64::try_from(lower)?)); - Ok(L::wrap_integer(out_property)) + Ok(L::wrap_integer(out_property.into_dyn())) }, ); map.insert( @@ -1089,7 +1098,7 @@ fn builtin_size_hint_methods<'a, L: TemplateLanguage<'a> + ?Sized>( function.expect_no_arguments()?; let out_property = self_property.and_then(|(_, upper)| Ok(upper.map(i64::try_from).transpose()?)); - Ok(L::wrap_integer_opt(out_property)) + Ok(L::wrap_integer_opt(out_property.into_dyn())) }, ); map.insert( @@ -1100,7 +1109,7 @@ fn builtin_size_hint_methods<'a, L: TemplateLanguage<'a> + ?Sized>( let exact = (Some(lower) == upper).then_some(lower); Ok(exact.map(i64::try_from).transpose()?) }); - Ok(L::wrap_integer_opt(out_property)) + Ok(L::wrap_integer_opt(out_property.into_dyn())) }, ); map.insert( @@ -1108,7 +1117,7 @@ fn builtin_size_hint_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|(_, upper)| upper == Some(0)); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map @@ -1128,7 +1137,7 @@ fn builtin_timestamp_methods<'a, L: TemplateLanguage<'a> + ?Sized>( let out_property = self_property.and_then(move |timestamp| { Ok(time_util::format_duration(×tamp, &now, &format)?) }); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -1147,7 +1156,7 @@ fn builtin_timestamp_methods<'a, L: TemplateLanguage<'a> + ?Sized>( ×tamp, &format, )?) }); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map.insert( @@ -1158,7 +1167,7 @@ fn builtin_timestamp_methods<'a, L: TemplateLanguage<'a> + ?Sized>( timestamp.tz_offset = 0; timestamp }); - Ok(L::wrap_timestamp(out_property)) + Ok(L::wrap_timestamp(out_property.into_dyn())) }, ); map.insert( @@ -1173,7 +1182,7 @@ fn builtin_timestamp_methods<'a, L: TemplateLanguage<'a> + ?Sized>( timestamp.tz_offset = tz_offset; timestamp }); - Ok(L::wrap_timestamp(out_property)) + Ok(L::wrap_timestamp(out_property.into_dyn())) }, ); map.insert( @@ -1191,7 +1200,7 @@ fn builtin_timestamp_methods<'a, L: TemplateLanguage<'a> + ?Sized>( }, )?; let out_property = self_property.map(move |timestamp| date_pattern.matches(×tamp)); - Ok(L::wrap_boolean(out_property)) + Ok(L::wrap_boolean(out_property.into_dyn())) }, ); map.insert("before", map["after"]); @@ -1208,7 +1217,7 @@ fn builtin_timestamp_range_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|time_range| time_range.start); - Ok(L::wrap_timestamp(out_property)) + Ok(L::wrap_timestamp(out_property.into_dyn())) }, ); map.insert( @@ -1216,7 +1225,7 @@ fn builtin_timestamp_range_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.map(|time_range| time_range.end); - Ok(L::wrap_timestamp(out_property)) + Ok(L::wrap_timestamp(out_property.into_dyn())) }, ); map.insert( @@ -1224,7 +1233,7 @@ fn builtin_timestamp_range_methods<'a, L: TemplateLanguage<'a> + ?Sized>( |_language, _diagnostics, _build_ctx, self_property, function| { function.expect_no_arguments()?; let out_property = self_property.and_then(|time_range| Ok(time_range.duration()?)); - Ok(L::wrap_string(out_property)) + Ok(L::wrap_string(out_property.into_dyn())) }, ); map @@ -1257,9 +1266,8 @@ pub fn build_formattable_list_method<'a, L, O>( self_property: impl TemplateProperty> + 'a, function: &FunctionCallNode, // TODO: Generic L: WrapProperty trait might be needed to support more - // list operations such as first()/slice(). For .map(), a simple callback - // works. For .filter(), redundant boxing is needed. - wrap_item: impl Fn(PropertyPlaceholder) -> L::Property, + // list operations such as first()/slice(). + wrap_item: impl Fn(Box + 'a>) -> L::Property, wrap_list: impl Fn(Box> + 'a>) -> L::Property, ) -> TemplateParseResult where @@ -1270,7 +1278,7 @@ where "len" => { function.expect_no_arguments()?; let out_property = self_property.and_then(|items| Ok(items.len().try_into()?)); - L::wrap_integer(out_property) + L::wrap_integer(out_property.into_dyn()) } "join" => { let [separator_node] = function.expect_exact_arguments()?; @@ -1310,7 +1318,7 @@ pub fn build_unformattable_list_method<'a, L, O>( build_ctx: &BuildContext, self_property: impl TemplateProperty> + 'a, function: &FunctionCallNode, - wrap_item: impl Fn(PropertyPlaceholder) -> L::Property, + wrap_item: impl Fn(Box + 'a>) -> L::Property, wrap_list: impl Fn(Box> + 'a>) -> L::Property, ) -> TemplateParseResult where @@ -1321,7 +1329,7 @@ where "len" => { function.expect_no_arguments()?; let out_property = self_property.and_then(|items| Ok(items.len().try_into()?)); - L::wrap_integer(out_property) + L::wrap_integer(out_property.into_dyn()) } // No "join" "filter" => build_filter_operation( @@ -1356,7 +1364,7 @@ fn build_filter_operation<'a, L, O, P, B>( build_ctx: &BuildContext, self_property: P, function: &FunctionCallNode, - wrap_item: impl Fn(PropertyPlaceholder) -> L::Property, + wrap_item: impl Fn(Box + 'a>) -> L::Property, wrap_list: impl Fn(Box + 'a>) -> L::Property, ) -> TemplateParseResult where @@ -1372,7 +1380,7 @@ where build_lambda_expression( build_ctx, lambda, - &[&|| wrap_item(item_placeholder.clone())], + &[&|| wrap_item(item_placeholder.clone().into_dyn())], |build_ctx, body| expect_boolean_expression(language, diagnostics, build_ctx, body), ) })?; @@ -1401,7 +1409,7 @@ fn build_map_operation<'a, L, O, P>( build_ctx: &BuildContext, self_property: P, function: &FunctionCallNode, - wrap_item: impl Fn(PropertyPlaceholder) -> L::Property, + wrap_item: impl Fn(Box + 'a>) -> L::Property, ) -> TemplateParseResult where L: TemplateLanguage<'a> + ?Sized, @@ -1415,7 +1423,7 @@ where build_lambda_expression( build_ctx, lambda, - &[&|| wrap_item(item_placeholder.clone())], + &[&|| wrap_item(item_placeholder.clone().into_dyn())], |build_ctx, body| expect_template_expression(language, diagnostics, build_ctx, body), ) })?; @@ -1648,7 +1656,9 @@ fn builtin_functions<'a, L: TemplateLanguage<'a> + ?Sized>() -> TemplateBuildFun .with_source(err) })?; // .decorated("", "") to trim leading/trailing whitespace - Ok(L::wrap_config_value(Literal(value.decorated("", "")))) + Ok(L::wrap_config_value( + Literal(value.decorated("", "")).into_dyn(), + )) }); map } @@ -1740,15 +1750,15 @@ pub fn build_expression<'a, L: TemplateLanguage<'a> + ?Sized>( } } ExpressionKind::Boolean(value) => { - let property = L::wrap_boolean(Literal(*value)); + let property = L::wrap_boolean(Literal(*value).into_dyn()); Ok(Expression::unlabeled(property)) } ExpressionKind::Integer(value) => { - let property = L::wrap_integer(Literal(*value)); + let property = L::wrap_integer(Literal(*value).into_dyn()); Ok(Expression::unlabeled(property)) } ExpressionKind::String(value) => { - let property = L::wrap_string(Literal(value.clone())); + let property = L::wrap_string(Literal(value.clone()).into_dyn()); Ok(Expression::unlabeled(property)) } ExpressionKind::Unary(op, arg_node) => { @@ -1817,12 +1827,12 @@ pub fn build<'a, C: Clone + 'a, L: TemplateLanguage<'a> + ?Sized>( node: &ExpressionNode, // TODO: Generic L: WrapProperty trait might be better. See the // comment in build_formattable_list_method(). - wrap_self: impl Fn(PropertyPlaceholder) -> L::Property, + wrap_self: impl Fn(Box + 'a>) -> L::Property, ) -> TemplateParseResult> { let self_placeholder = PropertyPlaceholder::new(); let build_ctx = BuildContext { local_variables: HashMap::new(), - self_variable: &|| wrap_self(self_placeholder.clone()), + self_variable: &|| wrap_self(self_placeholder.clone().into_dyn()), }; let template = expect_template_expression(language, diagnostics, &build_ctx, node)?; Ok(TemplateRenderer::new(template, self_placeholder)) @@ -1834,7 +1844,7 @@ pub fn parse<'a, C: Clone + 'a, L: TemplateLanguage<'a> + ?Sized>( diagnostics: &mut TemplateDiagnostics, template_text: &str, aliases_map: &TemplateAliasesMap, - wrap_self: impl Fn(PropertyPlaceholder) -> L::Property, + wrap_self: impl Fn(Box + 'a>) -> L::Property, ) -> TemplateParseResult> { let node = template_parser::parse(template_text, aliases_map)?; build(language, diagnostics, &node, wrap_self) @@ -2046,11 +2056,14 @@ mod tests { } } - // TODO: O doesn't have to be captured, but "currently, all type parameters - // are required to be mentioned in the precise captures list" as of rustc - // 1.85.0. - fn new_error_property(message: &str) -> impl TemplateProperty + use<'_, O> { - Literal(()).and_then(|()| Err(TemplatePropertyError(message.into()))) + fn literal<'a, O: Clone + 'a>(value: O) -> Box + 'a> { + Literal(value).into_dyn() + } + + fn new_error_property(message: &str) -> Box + '_> { + Literal(()) + .and_then(|()| Err(TemplatePropertyError(message.into()))) + .into_dyn() } fn new_signature(name: &str, email: &str) -> Signature { @@ -2071,9 +2084,9 @@ mod tests { #[test] fn test_parsed_tree() { let mut env = TestTemplateEnv::new(); - env.add_keyword("divergent", || L::wrap_boolean(Literal(false))); - env.add_keyword("empty", || L::wrap_boolean(Literal(true))); - env.add_keyword("hello", || L::wrap_string(Literal("Hello".to_owned()))); + env.add_keyword("divergent", || L::wrap_boolean(literal(false))); + env.add_keyword("empty", || L::wrap_boolean(literal(true))); + env.add_keyword("hello", || L::wrap_string(literal("Hello".to_owned()))); // Empty insta::assert_snapshot!(env.render_ok(r#" "#), @""); @@ -2100,8 +2113,8 @@ mod tests { #[test] fn test_parse_error() { let mut env = TestTemplateEnv::new(); - env.add_keyword("description", || L::wrap_string(Literal("".to_owned()))); - env.add_keyword("empty", || L::wrap_boolean(Literal(true))); + env.add_keyword("description", || L::wrap_string(literal("".to_owned()))); + env.add_keyword("empty", || L::wrap_boolean(literal(true))); insta::assert_snapshot!(env.parse_err(r#"description ()"#), @r" --> 1:13 @@ -2345,7 +2358,7 @@ mod tests { #[test] fn test_self_keyword() { let mut env = TestTemplateEnv::new(); - env.add_keyword("say_hello", || L::wrap_string(Literal("Hello".to_owned()))); + env.add_keyword("say_hello", || L::wrap_string(literal("Hello".to_owned()))); insta::assert_snapshot!(env.render_ok(r#"self.say_hello()"#), @"Hello"); insta::assert_snapshot!(env.parse_err(r#"self"#), @r" @@ -2366,9 +2379,9 @@ mod tests { insta::assert_snapshot!(env.render_ok(r#"if("a", true, false)"#), @"true"); env.add_keyword("sl0", || { - L::wrap_string_list(Literal::>(vec![])) + L::wrap_string_list(literal::>(vec![])) }); - env.add_keyword("sl1", || L::wrap_string_list(Literal(vec!["".to_owned()]))); + env.add_keyword("sl1", || L::wrap_string_list(literal(vec!["".to_owned()]))); insta::assert_snapshot!(env.render_ok(r#"if(sl0, true, false)"#), @"false"); insta::assert_snapshot!(env.render_ok(r#"if(sl1, true, false)"#), @"true"); @@ -2383,8 +2396,8 @@ mod tests { "); // Optional integer can be converted to boolean, and Some(0) is truthy. - env.add_keyword("none_i64", || L::wrap_integer_opt(Literal(None))); - env.add_keyword("some_i64", || L::wrap_integer_opt(Literal(Some(0)))); + env.add_keyword("none_i64", || L::wrap_integer_opt(literal(None))); + env.add_keyword("some_i64", || L::wrap_integer_opt(literal(Some(0)))); insta::assert_snapshot!(env.render_ok(r#"if(none_i64, true, false)"#), @"false"); insta::assert_snapshot!(env.render_ok(r#"if(some_i64, true, false)"#), @"true"); @@ -2406,10 +2419,10 @@ mod tests { "); env.add_keyword("empty_email", || { - L::wrap_email(Literal(Email("".to_owned()))) + L::wrap_email(literal(Email("".to_owned()))) }); env.add_keyword("nonempty_email", || { - L::wrap_email(Literal(Email("local@domain".to_owned()))) + L::wrap_email(literal(Email("local@domain".to_owned()))) }); insta::assert_snapshot!(env.render_ok(r#"if(empty_email, true, false)"#), @"false"); insta::assert_snapshot!(env.render_ok(r#"if(nonempty_email, true, false)"#), @"true"); @@ -2418,9 +2431,9 @@ mod tests { #[test] fn test_arithmetic_operation() { let mut env = TestTemplateEnv::new(); - env.add_keyword("none_i64", || L::wrap_integer_opt(Literal(None))); - env.add_keyword("some_i64", || L::wrap_integer_opt(Literal(Some(1)))); - env.add_keyword("i64_min", || L::wrap_integer(Literal(i64::MIN))); + env.add_keyword("none_i64", || L::wrap_integer_opt(literal(None))); + env.add_keyword("some_i64", || L::wrap_integer_opt(literal(Some(1)))); + env.add_keyword("i64_min", || L::wrap_integer(literal(i64::MIN))); insta::assert_snapshot!(env.render_ok(r#"-1"#), @"-1"); insta::assert_snapshot!(env.render_ok(r#"--2"#), @"2"); @@ -2455,10 +2468,10 @@ mod tests { fn test_logical_operation() { let mut env = TestTemplateEnv::new(); env.add_keyword("email1", || { - L::wrap_email(Literal(Email("local-1@domain".to_owned()))) + L::wrap_email(literal(Email("local-1@domain".to_owned()))) }); env.add_keyword("email2", || { - L::wrap_email(Literal(Email("local-2@domain".to_owned()))) + L::wrap_email(literal(Email("local-2@domain".to_owned()))) }); insta::assert_snapshot!(env.render_ok(r#"!false"#), @"true"); @@ -2497,8 +2510,8 @@ mod tests { #[test] fn test_list_method() { let mut env = TestTemplateEnv::new(); - env.add_keyword("empty", || L::wrap_boolean(Literal(true))); - env.add_keyword("sep", || L::wrap_string(Literal("sep".to_owned()))); + env.add_keyword("empty", || L::wrap_boolean(literal(true))); + env.add_keyword("sep", || L::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"); @@ -2614,7 +2627,7 @@ mod tests { fn test_string_method() { let mut env = TestTemplateEnv::new(); env.add_keyword("description", || { - L::wrap_string(Literal("description 1".to_owned())) + L::wrap_string(literal("description 1".to_owned())) }); env.add_keyword("bad_string", || L::wrap_string(new_error_property("Bad"))); @@ -2711,16 +2724,16 @@ mod tests { fn test_config_value_method() { let mut env = TestTemplateEnv::new(); env.add_keyword("boolean", || { - L::wrap_config_value(Literal(ConfigValue::from(true))) + L::wrap_config_value(literal(ConfigValue::from(true))) }); env.add_keyword("integer", || { - L::wrap_config_value(Literal(ConfigValue::from(42))) + L::wrap_config_value(literal(ConfigValue::from(42))) }); env.add_keyword("string", || { - L::wrap_config_value(Literal(ConfigValue::from("foo"))) + L::wrap_config_value(literal(ConfigValue::from("foo"))) }); env.add_keyword("string_list", || { - L::wrap_config_value(Literal(ConfigValue::from_iter(["foo", "bar"]))) + L::wrap_config_value(literal(ConfigValue::from_iter(["foo", "bar"]))) }); insta::assert_snapshot!(env.render_ok("boolean"), @"true"); @@ -2752,7 +2765,7 @@ mod tests { let mut env = TestTemplateEnv::new(); env.add_keyword("author", || { - L::wrap_signature(Literal(new_signature("Test User", "test.user@example.com"))) + L::wrap_signature(literal(new_signature("Test User", "test.user@example.com"))) }); insta::assert_snapshot!(env.render_ok(r#"author"#), @"Test User "); insta::assert_snapshot!(env.render_ok(r#"author.name()"#), @"Test User"); @@ -2760,7 +2773,7 @@ mod tests { insta::assert_snapshot!(env.render_ok(r#"author.username()"#), @"test.user"); env.add_keyword("author", || { - L::wrap_signature(Literal(new_signature( + L::wrap_signature(literal(new_signature( "Another Test User", "test.user@example.com", ))) @@ -2771,7 +2784,7 @@ mod tests { insta::assert_snapshot!(env.render_ok(r#"author.username()"#), @"test.user"); env.add_keyword("author", || { - L::wrap_signature(Literal(new_signature( + L::wrap_signature(literal(new_signature( "Test User", "test.user@invalid@example.com", ))) @@ -2782,14 +2795,14 @@ mod tests { insta::assert_snapshot!(env.render_ok(r#"author.username()"#), @"test.user"); env.add_keyword("author", || { - L::wrap_signature(Literal(new_signature("Test User", "test.user"))) + L::wrap_signature(literal(new_signature("Test User", "test.user"))) }); insta::assert_snapshot!(env.render_ok(r#"author"#), @"Test User "); insta::assert_snapshot!(env.render_ok(r#"author.email()"#), @"test.user"); insta::assert_snapshot!(env.render_ok(r#"author.username()"#), @"test.user"); env.add_keyword("author", || { - L::wrap_signature(Literal(new_signature( + L::wrap_signature(literal(new_signature( "Test User", "test.user+tag@example.com", ))) @@ -2799,14 +2812,14 @@ mod tests { insta::assert_snapshot!(env.render_ok(r#"author.username()"#), @"test.user+tag"); env.add_keyword("author", || { - L::wrap_signature(Literal(new_signature("Test User", "x@y"))) + L::wrap_signature(literal(new_signature("Test User", "x@y"))) }); insta::assert_snapshot!(env.render_ok(r#"author"#), @"Test User "); insta::assert_snapshot!(env.render_ok(r#"author.email()"#), @"x@y"); insta::assert_snapshot!(env.render_ok(r#"author.username()"#), @"x"); env.add_keyword("author", || { - L::wrap_signature(Literal(new_signature("", "test.user@example.com"))) + L::wrap_signature(literal(new_signature("", "test.user@example.com"))) }); insta::assert_snapshot!(env.render_ok(r#"author"#), @""); insta::assert_snapshot!(env.render_ok(r#"author.name()"#), @""); @@ -2814,7 +2827,7 @@ mod tests { insta::assert_snapshot!(env.render_ok(r#"author.username()"#), @"test.user"); env.add_keyword("author", || { - L::wrap_signature(Literal(new_signature("Test User", ""))) + L::wrap_signature(literal(new_signature("Test User", ""))) }); insta::assert_snapshot!(env.render_ok(r#"author"#), @"Test User"); insta::assert_snapshot!(env.render_ok(r#"author.name()"#), @"Test User"); @@ -2822,7 +2835,7 @@ mod tests { insta::assert_snapshot!(env.render_ok(r#"author.username()"#), @""); env.add_keyword("author", || { - L::wrap_signature(Literal(new_signature("", ""))) + L::wrap_signature(literal(new_signature("", ""))) }); insta::assert_snapshot!(env.render_ok(r#"author"#), @""); insta::assert_snapshot!(env.render_ok(r#"author.name()"#), @""); @@ -2834,19 +2847,19 @@ mod tests { fn test_size_hint_method() { let mut env = TestTemplateEnv::new(); - env.add_keyword("unbounded", || L::wrap_size_hint(Literal((5, None)))); + env.add_keyword("unbounded", || L::wrap_size_hint(literal((5, None)))); insta::assert_snapshot!(env.render_ok(r#"unbounded.lower()"#), @"5"); insta::assert_snapshot!(env.render_ok(r#"unbounded.upper()"#), @""); insta::assert_snapshot!(env.render_ok(r#"unbounded.exact()"#), @""); insta::assert_snapshot!(env.render_ok(r#"unbounded.zero()"#), @"false"); - env.add_keyword("bounded", || L::wrap_size_hint(Literal((0, Some(10))))); + env.add_keyword("bounded", || L::wrap_size_hint(literal((0, Some(10))))); insta::assert_snapshot!(env.render_ok(r#"bounded.lower()"#), @"0"); insta::assert_snapshot!(env.render_ok(r#"bounded.upper()"#), @"10"); insta::assert_snapshot!(env.render_ok(r#"bounded.exact()"#), @""); insta::assert_snapshot!(env.render_ok(r#"bounded.zero()"#), @"false"); - env.add_keyword("zero", || L::wrap_size_hint(Literal((0, Some(0))))); + env.add_keyword("zero", || L::wrap_size_hint(literal((0, Some(0))))); insta::assert_snapshot!(env.render_ok(r#"zero.lower()"#), @"0"); insta::assert_snapshot!(env.render_ok(r#"zero.upper()"#), @"0"); insta::assert_snapshot!(env.render_ok(r#"zero.exact()"#), @"0"); @@ -2856,7 +2869,7 @@ mod tests { #[test] fn test_timestamp_method() { let mut env = TestTemplateEnv::new(); - env.add_keyword("t0", || L::wrap_timestamp(Literal(new_timestamp(0, 0)))); + env.add_keyword("t0", || L::wrap_timestamp(literal(new_timestamp(0, 0)))); insta::assert_snapshot!( env.render_ok(r#"t0.format("%Y%m%d %H:%M:%S")"#), @@ -3107,7 +3120,7 @@ mod tests { #[test] fn test_label_function() { let mut env = TestTemplateEnv::new(); - env.add_keyword("empty", || L::wrap_boolean(Literal(true))); + env.add_keyword("empty", || L::wrap_boolean(literal(true))); env.add_color("error", crossterm::style::Color::DarkRed); env.add_color("warning", crossterm::style::Color::DarkYellow); @@ -3182,9 +3195,9 @@ mod tests { fn test_coalesce_function() { let mut env = TestTemplateEnv::new(); env.add_keyword("bad_string", || L::wrap_string(new_error_property("Bad"))); - env.add_keyword("empty_string", || L::wrap_string(Literal("".to_owned()))); + env.add_keyword("empty_string", || L::wrap_string(literal("".to_owned()))); env.add_keyword("non_empty_string", || { - L::wrap_string(Literal("a".to_owned())) + L::wrap_string(literal("a".to_owned())) }); insta::assert_snapshot!(env.render_ok(r#"coalesce()"#), @""); @@ -3205,8 +3218,8 @@ mod tests { #[test] fn test_concat_function() { let mut env = TestTemplateEnv::new(); - env.add_keyword("empty", || L::wrap_boolean(Literal(true))); - env.add_keyword("hidden", || L::wrap_boolean(Literal(false))); + env.add_keyword("empty", || L::wrap_boolean(literal(true))); + env.add_keyword("hidden", || L::wrap_boolean(literal(false))); env.add_color("empty", crossterm::style::Color::DarkGreen); env.add_color("error", crossterm::style::Color::DarkRed); env.add_color("warning", crossterm::style::Color::DarkYellow); @@ -3223,9 +3236,9 @@ mod tests { #[test] fn test_separate_function() { let mut env = TestTemplateEnv::new(); - env.add_keyword("description", || L::wrap_string(Literal("".to_owned()))); - env.add_keyword("empty", || L::wrap_boolean(Literal(true))); - env.add_keyword("hidden", || L::wrap_boolean(Literal(false))); + env.add_keyword("description", || L::wrap_string(literal("".to_owned()))); + env.add_keyword("empty", || L::wrap_boolean(literal(true))); + env.add_keyword("hidden", || L::wrap_boolean(literal(false))); env.add_color("empty", crossterm::style::Color::DarkGreen); env.add_color("error", crossterm::style::Color::DarkRed); env.add_color("warning", crossterm::style::Color::DarkYellow); @@ -3279,10 +3292,10 @@ mod tests { #[test] fn test_surround_function() { let mut env = TestTemplateEnv::new(); - env.add_keyword("lt", || L::wrap_string(Literal("<".to_owned()))); - env.add_keyword("gt", || L::wrap_string(Literal(">".to_owned()))); - env.add_keyword("content", || L::wrap_string(Literal("content".to_owned()))); - env.add_keyword("empty_content", || L::wrap_string(Literal("".to_owned()))); + env.add_keyword("lt", || L::wrap_string(literal("<".to_owned()))); + env.add_keyword("gt", || L::wrap_string(literal(">".to_owned()))); + env.add_keyword("content", || L::wrap_string(literal("content".to_owned()))); + env.add_keyword("empty_content", || L::wrap_string(literal("".to_owned()))); env.add_color("error", crossterm::style::Color::DarkRed); env.add_color("paren", crossterm::style::Color::Cyan);