From a28396fc86bd5e947e617520b2250dbc069bd8e9 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Fri, 17 Feb 2023 23:36:42 +0900 Subject: [PATCH] templater: extract "commit" property variants to separate enum Now it's ready to split template_parser/templater into base template functions and "commit" templater. I think Signature and Timestamp are basic types, so they aren't moved to CommitTemplatePropertyKind. Perhaps, a duration type from OpTemplate will also be added to CoreTemplatePropertyKind. --- src/template_parser.rs | 146 ++++++++++++++++++++++++----------------- 1 file changed, 86 insertions(+), 60 deletions(-) diff --git a/src/template_parser.rs b/src/template_parser.rs index 16527cbf4..88e182844 100644 --- a/src/template_parser.rs +++ b/src/template_parser.rs @@ -598,14 +598,6 @@ trait TemplateLanguage<'a> { &self, property: Box + 'a>, ) -> Self::Property; - fn wrap_commit_or_change_id( - &self, - property: Box> + 'a>, - ) -> Self::Property; - fn wrap_shortest_id_prefix( - &self, - property: Box + 'a>, - ) -> Self::Property; fn wrap_signature( &self, property: Box + 'a>, @@ -636,8 +628,6 @@ enum CoreTemplatePropertyKind<'a, I> { String(Box + 'a>), Boolean(Box + 'a>), Integer(Box + 'a>), - CommitOrChangeId(Box> + 'a>), - ShortestIdPrefix(Box + 'a>), Signature(Box + 'a>), Timestamp(Box + 'a>), } @@ -677,8 +667,6 @@ impl<'a, I: 'a> IntoTemplateProperty<'a, I> for CoreTemplatePropertyKind<'a, I> CoreTemplatePropertyKind::String(property) => wrap(property), CoreTemplatePropertyKind::Boolean(property) => wrap(property), CoreTemplatePropertyKind::Integer(property) => wrap(property), - CoreTemplatePropertyKind::CommitOrChangeId(property) => wrap(property), - CoreTemplatePropertyKind::ShortestIdPrefix(property) => wrap(property), CoreTemplatePropertyKind::Signature(property) => wrap(property), CoreTemplatePropertyKind::Timestamp(property) => wrap(property), } @@ -834,12 +822,6 @@ fn build_core_method<'a, L: TemplateLanguage<'a>>( CoreTemplatePropertyKind::Integer(property) => { build_integer_method(language, property, function) } - CoreTemplatePropertyKind::CommitOrChangeId(property) => { - build_commit_or_change_id_method(language, property, function) - } - CoreTemplatePropertyKind::ShortestIdPrefix(property) => { - build_shortest_id_prefix_method(language, property, function) - } CoreTemplatePropertyKind::Signature(property) => { build_signature_method(language, property, function) } @@ -894,11 +876,11 @@ fn build_integer_method<'a, L: TemplateLanguage<'a>>( Err(TemplateParseError::no_such_method("Integer", function)) } -fn build_commit_or_change_id_method<'a, L: TemplateLanguage<'a>>( - language: &L, - self_property: impl TemplateProperty> + 'a, +fn build_commit_or_change_id_method<'a>( + language: &CommitTemplateLanguage<'a, '_>, + self_property: impl TemplateProperty> + 'a, function: &FunctionCallNode, -) -> TemplateParseResult { +) -> TemplateParseResult> { let parse_optional_integer = |function| -> Result, TemplateParseError> { let ([], [len_node]) = expect_arguments(function)?; len_node @@ -940,11 +922,11 @@ fn build_commit_or_change_id_method<'a, L: TemplateLanguage<'a>>( Ok(property) } -fn build_shortest_id_prefix_method<'a, L: TemplateLanguage<'a>>( - language: &L, - self_property: impl TemplateProperty + 'a, +fn build_shortest_id_prefix_method<'a>( + language: &CommitTemplateLanguage<'a, '_>, + self_property: impl TemplateProperty + 'a, function: &FunctionCallNode, -) -> TemplateParseResult { +) -> TemplateParseResult> { let property = match function.name { "prefix" => { expect_no_arguments(function)?; @@ -1083,7 +1065,7 @@ fn build_commit_keyword<'a>( language: &CommitTemplateLanguage<'a, '_>, name: &str, span: pest::Span, -) -> TemplateParseResult> { +) -> TemplateParseResult> { fn wrap_fn<'a, O>( f: impl Fn(&Commit) -> O + 'a, ) -> Box + 'a> { @@ -1168,50 +1150,38 @@ struct CommitTemplateLanguage<'a, 'b> { impl<'a> TemplateLanguage<'a> for CommitTemplateLanguage<'a, '_> { type Context = Commit; - type Property = CoreTemplatePropertyKind<'a, Commit>; + type Property = CommitTemplatePropertyKind<'a>; // TODO: maybe generate wrap_() by macro? fn wrap_string( &self, property: Box + 'a>, ) -> Self::Property { - CoreTemplatePropertyKind::String(property) + CommitTemplatePropertyKind::Core(CoreTemplatePropertyKind::String(property)) } fn wrap_boolean( &self, property: Box + 'a>, ) -> Self::Property { - CoreTemplatePropertyKind::Boolean(property) + CommitTemplatePropertyKind::Core(CoreTemplatePropertyKind::Boolean(property)) } fn wrap_integer( &self, property: Box + 'a>, ) -> Self::Property { - CoreTemplatePropertyKind::Integer(property) - } - fn wrap_commit_or_change_id( - &self, - property: Box> + 'a>, - ) -> Self::Property { - CoreTemplatePropertyKind::CommitOrChangeId(property) - } - fn wrap_shortest_id_prefix( - &self, - property: Box + 'a>, - ) -> Self::Property { - CoreTemplatePropertyKind::ShortestIdPrefix(property) + CommitTemplatePropertyKind::Core(CoreTemplatePropertyKind::Integer(property)) } fn wrap_signature( &self, property: Box + 'a>, ) -> Self::Property { - CoreTemplatePropertyKind::Signature(property) + CommitTemplatePropertyKind::Core(CoreTemplatePropertyKind::Signature(property)) } fn wrap_timestamp( &self, property: Box + 'a>, ) -> Self::Property { - CoreTemplatePropertyKind::Timestamp(property) + CommitTemplatePropertyKind::Core(CoreTemplatePropertyKind::Timestamp(property)) } fn build_keyword(&self, name: &str, span: pest::Span) -> TemplateParseResult { @@ -1223,7 +1193,77 @@ impl<'a> TemplateLanguage<'a> for CommitTemplateLanguage<'a, '_> { property: Self::Property, function: &FunctionCallNode, ) -> TemplateParseResult { - build_core_method(self, property, function) + match property { + CommitTemplatePropertyKind::Core(property) => { + build_core_method(self, property, function) + } + CommitTemplatePropertyKind::CommitOrChangeId(property) => { + build_commit_or_change_id_method(self, property, function) + } + CommitTemplatePropertyKind::ShortestIdPrefix(property) => { + build_shortest_id_prefix_method(self, property, function) + } + } + } +} + +// If we need to add multiple languages that support Commit types, this can be +// turned into a trait which extends TemplateLanguage. +impl<'a> CommitTemplateLanguage<'a, '_> { + fn wrap_commit_or_change_id( + &self, + property: Box> + 'a>, + ) -> CommitTemplatePropertyKind<'a> { + CommitTemplatePropertyKind::CommitOrChangeId(property) + } + + fn wrap_shortest_id_prefix( + &self, + property: Box + 'a>, + ) -> CommitTemplatePropertyKind<'a> { + CommitTemplatePropertyKind::ShortestIdPrefix(property) + } +} + +enum CommitTemplatePropertyKind<'a> { + Core(CoreTemplatePropertyKind<'a, Commit>), + CommitOrChangeId(Box> + 'a>), + ShortestIdPrefix(Box + 'a>), +} + +impl<'a> IntoTemplateProperty<'a, Commit> for CommitTemplatePropertyKind<'a> { + fn try_into_boolean(self) -> Option + 'a>> { + match self { + CommitTemplatePropertyKind::Core(property) => property.try_into_boolean(), + _ => None, + } + } + + fn try_into_integer(self) -> Option + 'a>> { + match self { + CommitTemplatePropertyKind::Core(property) => property.try_into_integer(), + _ => None, + } + } + + fn into_plain_text(self) -> Box + 'a> { + match self { + CommitTemplatePropertyKind::Core(property) => property.into_plain_text(), + _ => Box::new(PlainTextFormattedProperty::new(self.into_template())), + } + } + + fn into_template(self) -> Box + 'a> { + fn wrap<'a, O: Template<()> + 'a>( + property: Box + 'a>, + ) -> Box + 'a> { + Box::new(FormattablePropertyTemplate::new(property)) + } + match self { + CommitTemplatePropertyKind::Core(property) => property.into_template(), + CommitTemplatePropertyKind::CommitOrChangeId(property) => wrap(property), + CommitTemplatePropertyKind::ShortestIdPrefix(property) => wrap(property), + } } } @@ -1268,20 +1308,6 @@ mod tests { ) -> Self::Property { CoreTemplatePropertyKind::Integer(property) } - fn wrap_commit_or_change_id( - &self, - property: Box< - dyn TemplateProperty> + 'static, - >, - ) -> Self::Property { - CoreTemplatePropertyKind::CommitOrChangeId(property) - } - fn wrap_shortest_id_prefix( - &self, - property: Box + 'static>, - ) -> Self::Property { - CoreTemplatePropertyKind::ShortestIdPrefix(property) - } fn wrap_signature( &self, property: Box + 'static>,