templater: move core wrap_*() functions to property wrapper type

I think this was remainder of the old design where wrap_*() functions took
&TemplateLanguage as self argument. Since the wrapper type implements accessor
functions like .try_into_boolean(), it makes sense that the same type implements
::wrap_boolean(), etc.

These .wrap_<T>() functions will become generic over T.
This commit is contained in:
Yuya Nishihara 2025-04-30 12:10:59 +09:00
parent 577a484d1d
commit 7643364a76
4 changed files with 80 additions and 24 deletions

View File

@ -79,6 +79,7 @@ use crate::template_builder::merge_fn_map;
use crate::template_builder::BuildContext;
use crate::template_builder::CoreTemplateBuildFnTable;
use crate::template_builder::CoreTemplatePropertyKind;
use crate::template_builder::CoreTemplatePropertyVar;
use crate::template_builder::IntoTemplateProperty;
use crate::template_builder::TemplateBuildMethodFnMap;
use crate::template_builder::TemplateLanguage;
@ -164,8 +165,6 @@ impl<'repo> CommitTemplateLanguage<'repo> {
impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
type Property = CommitTemplatePropertyKind<'repo>;
template_builder::impl_core_wrap_property_fns!('repo, CommitTemplatePropertyKind::Core);
fn settings(&self) -> &UserSettings {
self.repo.base_repo().settings()
}
@ -498,6 +497,10 @@ pub enum CommitTemplatePropertyKind<'repo> {
TrailerList(BoxedTemplateProperty<'repo, Vec<Trailer>>),
}
impl<'repo> CoreTemplatePropertyVar<'repo> for CommitTemplatePropertyKind<'repo> {
template_builder::impl_core_wrap_property_fns!('repo, CommitTemplatePropertyKind::Core);
}
impl<'repo> IntoTemplateProperty<'repo> for CommitTemplatePropertyKind<'repo> {
fn type_name(&self) -> &'static str {
match self {

View File

@ -21,6 +21,7 @@ use crate::template_builder;
use crate::template_builder::BuildContext;
use crate::template_builder::CoreTemplateBuildFnTable;
use crate::template_builder::CoreTemplatePropertyKind;
use crate::template_builder::CoreTemplatePropertyVar;
use crate::template_builder::IntoTemplateProperty;
use crate::template_builder::TemplateLanguage;
use crate::template_parser;
@ -90,8 +91,6 @@ impl<'a, C> GenericTemplateLanguage<'a, C> {
impl<'a, C> TemplateLanguage<'a> for GenericTemplateLanguage<'a, C> {
type Property = GenericTemplatePropertyKind<'a, C>;
template_builder::impl_core_wrap_property_fns!('a, GenericTemplatePropertyKind::Core);
fn settings(&self) -> &UserSettings {
&self.settings
}
@ -141,6 +140,10 @@ pub enum GenericTemplatePropertyKind<'a, C> {
Self_(BoxedTemplateProperty<'a, C>),
}
impl<'a, C> CoreTemplatePropertyVar<'a> for GenericTemplatePropertyKind<'a, C> {
template_builder::impl_core_wrap_property_fns!('a, GenericTemplatePropertyKind::Core);
}
impl<'a, C> IntoTemplateProperty<'a> for GenericTemplatePropertyKind<'a, C> {
fn type_name(&self) -> &'static str {
match self {

View File

@ -30,6 +30,7 @@ use crate::template_builder::merge_fn_map;
use crate::template_builder::BuildContext;
use crate::template_builder::CoreTemplateBuildFnTable;
use crate::template_builder::CoreTemplatePropertyKind;
use crate::template_builder::CoreTemplatePropertyVar;
use crate::template_builder::IntoTemplateProperty;
use crate::template_builder::TemplateBuildMethodFnMap;
use crate::template_builder::TemplateLanguage;
@ -88,8 +89,6 @@ impl OperationTemplateLanguage {
impl TemplateLanguage<'static> for OperationTemplateLanguage {
type Property = OperationTemplatePropertyKind;
template_builder::impl_core_wrap_property_fns!('static, OperationTemplatePropertyKind::Core);
fn settings(&self) -> &UserSettings {
self.repo_loader.settings()
}
@ -155,6 +154,10 @@ pub enum OperationTemplatePropertyKind {
OperationId(BoxedTemplateProperty<'static, OperationId>),
}
impl CoreTemplatePropertyVar<'static> for OperationTemplatePropertyKind {
template_builder::impl_core_wrap_property_fns!('static, OperationTemplatePropertyKind::Core);
}
impl IntoTemplateProperty<'static> for OperationTemplatePropertyKind {
fn type_name(&self) -> &'static str {
match self {

View File

@ -68,22 +68,50 @@ use crate::time_util;
/// Callbacks to build language-specific evaluation objects from AST nodes.
pub trait TemplateLanguage<'a> {
type Property: IntoTemplateProperty<'a>;
type Property: CoreTemplatePropertyVar<'a> + IntoTemplateProperty<'a>;
fn wrap_string(property: BoxedTemplateProperty<'a, String>) -> Self::Property;
fn wrap_string_list(property: BoxedTemplateProperty<'a, Vec<String>>) -> Self::Property;
fn wrap_boolean(property: BoxedTemplateProperty<'a, bool>) -> Self::Property;
fn wrap_integer(property: BoxedTemplateProperty<'a, i64>) -> Self::Property;
fn wrap_integer_opt(property: BoxedTemplateProperty<'a, Option<i64>>) -> Self::Property;
fn wrap_config_value(property: BoxedTemplateProperty<'a, ConfigValue>) -> Self::Property;
fn wrap_signature(property: BoxedTemplateProperty<'a, Signature>) -> Self::Property;
fn wrap_email(property: BoxedTemplateProperty<'a, Email>) -> Self::Property;
fn wrap_size_hint(property: BoxedTemplateProperty<'a, SizeHint>) -> Self::Property;
fn wrap_timestamp(property: BoxedTemplateProperty<'a, Timestamp>) -> Self::Property;
fn wrap_timestamp_range(property: BoxedTemplateProperty<'a, TimestampRange>) -> Self::Property;
// TODO: delete
fn wrap_string(property: BoxedTemplateProperty<'a, String>) -> Self::Property {
Self::Property::wrap_string(property)
}
fn wrap_string_list(property: BoxedTemplateProperty<'a, Vec<String>>) -> Self::Property {
Self::Property::wrap_string_list(property)
}
fn wrap_boolean(property: BoxedTemplateProperty<'a, bool>) -> Self::Property {
Self::Property::wrap_boolean(property)
}
fn wrap_integer(property: BoxedTemplateProperty<'a, i64>) -> Self::Property {
Self::Property::wrap_integer(property)
}
fn wrap_integer_opt(property: BoxedTemplateProperty<'a, Option<i64>>) -> Self::Property {
Self::Property::wrap_integer_opt(property)
}
fn wrap_config_value(property: BoxedTemplateProperty<'a, ConfigValue>) -> Self::Property {
Self::Property::wrap_config_value(property)
}
fn wrap_signature(property: BoxedTemplateProperty<'a, Signature>) -> Self::Property {
Self::Property::wrap_signature(property)
}
fn wrap_email(property: BoxedTemplateProperty<'a, Email>) -> Self::Property {
Self::Property::wrap_email(property)
}
fn wrap_size_hint(property: BoxedTemplateProperty<'a, SizeHint>) -> Self::Property {
Self::Property::wrap_size_hint(property)
}
fn wrap_timestamp(property: BoxedTemplateProperty<'a, Timestamp>) -> Self::Property {
Self::Property::wrap_timestamp(property)
}
fn wrap_timestamp_range(property: BoxedTemplateProperty<'a, TimestampRange>) -> Self::Property {
Self::Property::wrap_timestamp_range(property)
}
fn wrap_template(template: Box<dyn Template + 'a>) -> Self::Property;
fn wrap_list_template(template: Box<dyn ListTemplate + 'a>) -> Self::Property;
// TODO: delete
fn wrap_template(template: Box<dyn Template + 'a>) -> Self::Property {
Self::Property::wrap_template(template)
}
fn wrap_list_template(template: Box<dyn ListTemplate + 'a>) -> Self::Property {
Self::Property::wrap_list_template(template)
}
fn settings(&self) -> &UserSettings;
@ -107,7 +135,7 @@ pub trait TemplateLanguage<'a> {
) -> TemplateParseResult<Self::Property>;
}
/// Implements `TemplateLanguage::wrap_<type>()` functions.
/// Implements `CoreTemplatePropertyVar::wrap_<type>()` functions.
///
/// - `impl_core_wrap_property_fns('a)` for `CoreTemplatePropertyKind`,
/// - `impl_core_wrap_property_fns('a, MyKind::Core)` for `MyKind::Core(..)`.
@ -133,13 +161,13 @@ macro_rules! impl_core_wrap_property_fns {
);
fn wrap_template(
template: Box<dyn $crate::templater::Template + $a>,
) -> Self::Property {
) -> Self {
use $crate::template_builder::CoreTemplatePropertyKind as Kind;
$outer(Kind::Template(template))
}
fn wrap_list_template(
template: Box<dyn $crate::templater::ListTemplate + $a>,
) -> Self::Property {
) -> Self {
use $crate::template_builder::CoreTemplatePropertyKind as Kind;
$outer(Kind::ListTemplate(template))
}
@ -151,7 +179,7 @@ macro_rules! impl_wrap_property_fns {
$(
fn $func(
property: $crate::templater::BoxedTemplateProperty<$a, $ty>,
) -> Self::Property {
) -> Self {
use $kind as Kind; // https://github.com/rust-lang/rust/issues/48067
$outer(Kind::$var(property))
}
@ -162,7 +190,26 @@ macro_rules! impl_wrap_property_fns {
pub(crate) use impl_core_wrap_property_fns;
pub(crate) use impl_wrap_property_fns;
/// Wrapper for the core template property types.
pub trait CoreTemplatePropertyVar<'a> {
fn wrap_string(property: BoxedTemplateProperty<'a, String>) -> Self;
fn wrap_string_list(property: BoxedTemplateProperty<'a, Vec<String>>) -> Self;
fn wrap_boolean(property: BoxedTemplateProperty<'a, bool>) -> Self;
fn wrap_integer(property: BoxedTemplateProperty<'a, i64>) -> Self;
fn wrap_integer_opt(property: BoxedTemplateProperty<'a, Option<i64>>) -> Self;
fn wrap_config_value(property: BoxedTemplateProperty<'a, ConfigValue>) -> Self;
fn wrap_signature(property: BoxedTemplateProperty<'a, Signature>) -> Self;
fn wrap_email(property: BoxedTemplateProperty<'a, Email>) -> Self;
fn wrap_size_hint(property: BoxedTemplateProperty<'a, SizeHint>) -> Self;
fn wrap_timestamp(property: BoxedTemplateProperty<'a, Timestamp>) -> Self;
fn wrap_timestamp_range(property: BoxedTemplateProperty<'a, TimestampRange>) -> Self;
fn wrap_template(template: Box<dyn Template + 'a>) -> Self;
fn wrap_list_template(template: Box<dyn ListTemplate + 'a>) -> Self;
}
/// Provides access to basic template property types.
// TODO: merge with CoreTemplatePropertyVar<'a>?
pub trait IntoTemplateProperty<'a> {
/// Type name of the property output.
fn type_name(&self) -> &'static str;