mirror of
https://github.com/martinvonz/jj.git
synced 2025-05-05 23:42:50 +00:00
templater: add property.into_dyn() helper
I'm going to move Box<dyn _> conversion to callers, so there will be more places to use this helper.
This commit is contained in:
parent
533fb5e4bb
commit
96b633a091
@ -202,14 +202,8 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
|
|||||||
let type_name = "Commit";
|
let type_name = "Commit";
|
||||||
let table = &self.build_fn_table.commit_methods;
|
let table = &self.build_fn_table.commit_methods;
|
||||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||||
let inner_property = property.try_unwrap(type_name);
|
let inner_property = property.try_unwrap(type_name).into_dyn();
|
||||||
build(
|
build(self, diagnostics, build_ctx, inner_property, function)
|
||||||
self,
|
|
||||||
diagnostics,
|
|
||||||
build_ctx,
|
|
||||||
Box::new(inner_property),
|
|
||||||
function,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
CommitTemplatePropertyKind::CommitList(property) => {
|
CommitTemplatePropertyKind::CommitList(property) => {
|
||||||
// TODO: migrate to table?
|
// TODO: migrate to table?
|
||||||
@ -232,14 +226,8 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
|
|||||||
let type_name = "CommitRef";
|
let type_name = "CommitRef";
|
||||||
let table = &self.build_fn_table.commit_ref_methods;
|
let table = &self.build_fn_table.commit_ref_methods;
|
||||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||||
let inner_property = property.try_unwrap(type_name);
|
let inner_property = property.try_unwrap(type_name).into_dyn();
|
||||||
build(
|
build(self, diagnostics, build_ctx, inner_property, function)
|
||||||
self,
|
|
||||||
diagnostics,
|
|
||||||
build_ctx,
|
|
||||||
Box::new(inner_property),
|
|
||||||
function,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
CommitTemplatePropertyKind::CommitRefList(property) => {
|
CommitTemplatePropertyKind::CommitRefList(property) => {
|
||||||
// TODO: migrate to table?
|
// TODO: migrate to table?
|
||||||
@ -262,14 +250,8 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
|
|||||||
let type_name = "RepoPath";
|
let type_name = "RepoPath";
|
||||||
let table = &self.build_fn_table.repo_path_methods;
|
let table = &self.build_fn_table.repo_path_methods;
|
||||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||||
let inner_property = property.try_unwrap(type_name);
|
let inner_property = property.try_unwrap(type_name).into_dyn();
|
||||||
build(
|
build(self, diagnostics, build_ctx, inner_property, function)
|
||||||
self,
|
|
||||||
diagnostics,
|
|
||||||
build_ctx,
|
|
||||||
Box::new(inner_property),
|
|
||||||
function,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
CommitTemplatePropertyKind::CommitOrChangeId(property) => {
|
CommitTemplatePropertyKind::CommitOrChangeId(property) => {
|
||||||
let table = &self.build_fn_table.commit_or_change_id_methods;
|
let table = &self.build_fn_table.commit_or_change_id_methods;
|
||||||
@ -313,21 +295,15 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
|
|||||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||||
// Strip off formatting parameters which are needed only for the
|
// Strip off formatting parameters which are needed only for the
|
||||||
// default template output.
|
// default template output.
|
||||||
let property = Box::new(property.map(|formatted| formatted.stats));
|
let property = property.map(|formatted| formatted.stats).into_dyn();
|
||||||
build(self, diagnostics, build_ctx, property, function)
|
build(self, diagnostics, build_ctx, property, function)
|
||||||
}
|
}
|
||||||
CommitTemplatePropertyKind::CryptographicSignatureOpt(property) => {
|
CommitTemplatePropertyKind::CryptographicSignatureOpt(property) => {
|
||||||
let type_name = "CryptographicSignature";
|
let type_name = "CryptographicSignature";
|
||||||
let table = &self.build_fn_table.cryptographic_signature_methods;
|
let table = &self.build_fn_table.cryptographic_signature_methods;
|
||||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||||
let inner_property = property.try_unwrap(type_name);
|
let inner_property = property.try_unwrap(type_name).into_dyn();
|
||||||
build(
|
build(self, diagnostics, build_ctx, inner_property, function)
|
||||||
self,
|
|
||||||
diagnostics,
|
|
||||||
build_ctx,
|
|
||||||
Box::new(inner_property),
|
|
||||||
function,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
CommitTemplatePropertyKind::AnnotationLine(property) => {
|
CommitTemplatePropertyKind::AnnotationLine(property) => {
|
||||||
let type_name = "AnnotationLine";
|
let type_name = "AnnotationLine";
|
||||||
@ -557,21 +533,21 @@ impl<'repo> IntoTemplateProperty<'repo> for CommitTemplatePropertyKind<'repo> {
|
|||||||
CommitTemplatePropertyKind::Core(property) => property.try_into_boolean(),
|
CommitTemplatePropertyKind::Core(property) => property.try_into_boolean(),
|
||||||
CommitTemplatePropertyKind::Commit(_) => None,
|
CommitTemplatePropertyKind::Commit(_) => None,
|
||||||
CommitTemplatePropertyKind::CommitOpt(property) => {
|
CommitTemplatePropertyKind::CommitOpt(property) => {
|
||||||
Some(Box::new(property.map(|opt| opt.is_some())))
|
Some(property.map(|opt| opt.is_some()).into_dyn())
|
||||||
}
|
}
|
||||||
CommitTemplatePropertyKind::CommitList(property) => {
|
CommitTemplatePropertyKind::CommitList(property) => {
|
||||||
Some(Box::new(property.map(|l| !l.is_empty())))
|
Some(property.map(|l| !l.is_empty()).into_dyn())
|
||||||
}
|
}
|
||||||
CommitTemplatePropertyKind::CommitRef(_) => None,
|
CommitTemplatePropertyKind::CommitRef(_) => None,
|
||||||
CommitTemplatePropertyKind::CommitRefOpt(property) => {
|
CommitTemplatePropertyKind::CommitRefOpt(property) => {
|
||||||
Some(Box::new(property.map(|opt| opt.is_some())))
|
Some(property.map(|opt| opt.is_some()).into_dyn())
|
||||||
}
|
}
|
||||||
CommitTemplatePropertyKind::CommitRefList(property) => {
|
CommitTemplatePropertyKind::CommitRefList(property) => {
|
||||||
Some(Box::new(property.map(|l| !l.is_empty())))
|
Some(property.map(|l| !l.is_empty()).into_dyn())
|
||||||
}
|
}
|
||||||
CommitTemplatePropertyKind::RepoPath(_) => None,
|
CommitTemplatePropertyKind::RepoPath(_) => None,
|
||||||
CommitTemplatePropertyKind::RepoPathOpt(property) => {
|
CommitTemplatePropertyKind::RepoPathOpt(property) => {
|
||||||
Some(Box::new(property.map(|opt| opt.is_some())))
|
Some(property.map(|opt| opt.is_some()).into_dyn())
|
||||||
}
|
}
|
||||||
CommitTemplatePropertyKind::CommitOrChangeId(_) => None,
|
CommitTemplatePropertyKind::CommitOrChangeId(_) => None,
|
||||||
CommitTemplatePropertyKind::ShortestIdPrefix(_) => None,
|
CommitTemplatePropertyKind::ShortestIdPrefix(_) => None,
|
||||||
@ -580,17 +556,17 @@ impl<'repo> IntoTemplateProperty<'repo> for CommitTemplatePropertyKind<'repo> {
|
|||||||
CommitTemplatePropertyKind::TreeDiff(_) => None,
|
CommitTemplatePropertyKind::TreeDiff(_) => None,
|
||||||
CommitTemplatePropertyKind::TreeDiffEntry(_) => None,
|
CommitTemplatePropertyKind::TreeDiffEntry(_) => None,
|
||||||
CommitTemplatePropertyKind::TreeDiffEntryList(property) => {
|
CommitTemplatePropertyKind::TreeDiffEntryList(property) => {
|
||||||
Some(Box::new(property.map(|l| !l.is_empty())))
|
Some(property.map(|l| !l.is_empty()).into_dyn())
|
||||||
}
|
}
|
||||||
CommitTemplatePropertyKind::TreeEntry(_) => None,
|
CommitTemplatePropertyKind::TreeEntry(_) => None,
|
||||||
CommitTemplatePropertyKind::DiffStats(_) => None,
|
CommitTemplatePropertyKind::DiffStats(_) => None,
|
||||||
CommitTemplatePropertyKind::CryptographicSignatureOpt(property) => {
|
CommitTemplatePropertyKind::CryptographicSignatureOpt(property) => {
|
||||||
Some(Box::new(property.map(|sig| sig.is_some())))
|
Some(property.map(|sig| sig.is_some()).into_dyn())
|
||||||
}
|
}
|
||||||
CommitTemplatePropertyKind::AnnotationLine(_) => None,
|
CommitTemplatePropertyKind::AnnotationLine(_) => None,
|
||||||
CommitTemplatePropertyKind::Trailer(_) => None,
|
CommitTemplatePropertyKind::Trailer(_) => None,
|
||||||
CommitTemplatePropertyKind::TrailerList(property) => {
|
CommitTemplatePropertyKind::TrailerList(property) => {
|
||||||
Some(Box::new(property.map(|l| !l.is_empty())))
|
Some(property.map(|l| !l.is_empty()).into_dyn())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -607,7 +583,7 @@ impl<'repo> IntoTemplateProperty<'repo> for CommitTemplatePropertyKind<'repo> {
|
|||||||
CommitTemplatePropertyKind::Core(property) => property.try_into_plain_text(),
|
CommitTemplatePropertyKind::Core(property) => property.try_into_plain_text(),
|
||||||
_ => {
|
_ => {
|
||||||
let template = self.try_into_template()?;
|
let template = self.try_into_template()?;
|
||||||
Some(Box::new(PlainTextFormattedProperty::new(template)))
|
Some(PlainTextFormattedProperty::new(template).into_dyn())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@ impl IntoTemplateProperty<'static> for OperationTemplatePropertyKind {
|
|||||||
OperationTemplatePropertyKind::Core(property) => property.try_into_plain_text(),
|
OperationTemplatePropertyKind::Core(property) => property.try_into_plain_text(),
|
||||||
_ => {
|
_ => {
|
||||||
let template = self.try_into_template()?;
|
let template = self.try_into_template()?;
|
||||||
Some(Box::new(PlainTextFormattedProperty::new(template)))
|
Some(PlainTextFormattedProperty::new(template).into_dyn())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,20 +237,20 @@ impl<'a> IntoTemplateProperty<'a> for CoreTemplatePropertyKind<'a> {
|
|||||||
fn try_into_boolean(self) -> Option<Box<dyn TemplateProperty<Output = bool> + 'a>> {
|
fn try_into_boolean(self) -> Option<Box<dyn TemplateProperty<Output = bool> + 'a>> {
|
||||||
match self {
|
match self {
|
||||||
CoreTemplatePropertyKind::String(property) => {
|
CoreTemplatePropertyKind::String(property) => {
|
||||||
Some(Box::new(property.map(|s| !s.is_empty())))
|
Some(property.map(|s| !s.is_empty()).into_dyn())
|
||||||
}
|
}
|
||||||
CoreTemplatePropertyKind::StringList(property) => {
|
CoreTemplatePropertyKind::StringList(property) => {
|
||||||
Some(Box::new(property.map(|l| !l.is_empty())))
|
Some(property.map(|l| !l.is_empty()).into_dyn())
|
||||||
}
|
}
|
||||||
CoreTemplatePropertyKind::Boolean(property) => Some(property),
|
CoreTemplatePropertyKind::Boolean(property) => Some(property),
|
||||||
CoreTemplatePropertyKind::Integer(_) => None,
|
CoreTemplatePropertyKind::Integer(_) => None,
|
||||||
CoreTemplatePropertyKind::IntegerOpt(property) => {
|
CoreTemplatePropertyKind::IntegerOpt(property) => {
|
||||||
Some(Box::new(property.map(|opt| opt.is_some())))
|
Some(property.map(|opt| opt.is_some()).into_dyn())
|
||||||
}
|
}
|
||||||
CoreTemplatePropertyKind::ConfigValue(_) => None,
|
CoreTemplatePropertyKind::ConfigValue(_) => None,
|
||||||
CoreTemplatePropertyKind::Signature(_) => None,
|
CoreTemplatePropertyKind::Signature(_) => None,
|
||||||
CoreTemplatePropertyKind::Email(property) => {
|
CoreTemplatePropertyKind::Email(property) => {
|
||||||
Some(Box::new(property.map(|e| !e.0.is_empty())))
|
Some(property.map(|e| !e.0.is_empty()).into_dyn())
|
||||||
}
|
}
|
||||||
CoreTemplatePropertyKind::SizeHint(_) => None,
|
CoreTemplatePropertyKind::SizeHint(_) => None,
|
||||||
CoreTemplatePropertyKind::Timestamp(_) => None,
|
CoreTemplatePropertyKind::Timestamp(_) => None,
|
||||||
@ -267,7 +267,7 @@ impl<'a> IntoTemplateProperty<'a> for CoreTemplatePropertyKind<'a> {
|
|||||||
match self {
|
match self {
|
||||||
CoreTemplatePropertyKind::Integer(property) => Some(property),
|
CoreTemplatePropertyKind::Integer(property) => Some(property),
|
||||||
CoreTemplatePropertyKind::IntegerOpt(property) => {
|
CoreTemplatePropertyKind::IntegerOpt(property) => {
|
||||||
Some(Box::new(property.try_unwrap("Integer")))
|
Some(property.try_unwrap("Integer").into_dyn())
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@ -278,7 +278,7 @@ impl<'a> IntoTemplateProperty<'a> for CoreTemplatePropertyKind<'a> {
|
|||||||
CoreTemplatePropertyKind::String(property) => Some(property),
|
CoreTemplatePropertyKind::String(property) => Some(property),
|
||||||
_ => {
|
_ => {
|
||||||
let template = self.try_into_template()?;
|
let template = self.try_into_template()?;
|
||||||
Some(Box::new(PlainTextFormattedProperty::new(template)))
|
Some(PlainTextFormattedProperty::new(template).into_dyn())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -304,22 +304,22 @@ impl<'a> IntoTemplateProperty<'a> for CoreTemplatePropertyKind<'a> {
|
|||||||
fn try_into_eq(self, other: Self) -> Option<Box<dyn TemplateProperty<Output = bool> + 'a>> {
|
fn try_into_eq(self, other: Self) -> Option<Box<dyn TemplateProperty<Output = bool> + 'a>> {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(CoreTemplatePropertyKind::String(lhs), CoreTemplatePropertyKind::String(rhs)) => {
|
(CoreTemplatePropertyKind::String(lhs), CoreTemplatePropertyKind::String(rhs)) => {
|
||||||
Some(Box::new((lhs, rhs).map(|(l, r)| l == r)))
|
Some((lhs, rhs).map(|(l, r)| l == r).into_dyn())
|
||||||
}
|
}
|
||||||
(CoreTemplatePropertyKind::String(lhs), CoreTemplatePropertyKind::Email(rhs)) => {
|
(CoreTemplatePropertyKind::String(lhs), CoreTemplatePropertyKind::Email(rhs)) => {
|
||||||
Some(Box::new((lhs, rhs).map(|(l, r)| l == r.0)))
|
Some((lhs, rhs).map(|(l, r)| l == r.0).into_dyn())
|
||||||
}
|
}
|
||||||
(CoreTemplatePropertyKind::Boolean(lhs), CoreTemplatePropertyKind::Boolean(rhs)) => {
|
(CoreTemplatePropertyKind::Boolean(lhs), CoreTemplatePropertyKind::Boolean(rhs)) => {
|
||||||
Some(Box::new((lhs, rhs).map(|(l, r)| l == r)))
|
Some((lhs, rhs).map(|(l, r)| l == r).into_dyn())
|
||||||
}
|
}
|
||||||
(CoreTemplatePropertyKind::Integer(lhs), CoreTemplatePropertyKind::Integer(rhs)) => {
|
(CoreTemplatePropertyKind::Integer(lhs), CoreTemplatePropertyKind::Integer(rhs)) => {
|
||||||
Some(Box::new((lhs, rhs).map(|(l, r)| l == r)))
|
Some((lhs, rhs).map(|(l, r)| l == r).into_dyn())
|
||||||
}
|
}
|
||||||
(CoreTemplatePropertyKind::Email(lhs), CoreTemplatePropertyKind::Email(rhs)) => {
|
(CoreTemplatePropertyKind::Email(lhs), CoreTemplatePropertyKind::Email(rhs)) => {
|
||||||
Some(Box::new((lhs, rhs).map(|(l, r)| l == r)))
|
Some((lhs, rhs).map(|(l, r)| l == r).into_dyn())
|
||||||
}
|
}
|
||||||
(CoreTemplatePropertyKind::Email(lhs), CoreTemplatePropertyKind::String(rhs)) => {
|
(CoreTemplatePropertyKind::Email(lhs), CoreTemplatePropertyKind::String(rhs)) => {
|
||||||
Some(Box::new((lhs, rhs).map(|(l, r)| l.0 == r)))
|
Some((lhs, rhs).map(|(l, r)| l.0 == r).into_dyn())
|
||||||
}
|
}
|
||||||
(CoreTemplatePropertyKind::String(_), _) => None,
|
(CoreTemplatePropertyKind::String(_), _) => None,
|
||||||
(CoreTemplatePropertyKind::StringList(_), _) => None,
|
(CoreTemplatePropertyKind::StringList(_), _) => None,
|
||||||
@ -343,7 +343,7 @@ impl<'a> IntoTemplateProperty<'a> for CoreTemplatePropertyKind<'a> {
|
|||||||
) -> Option<Box<dyn TemplateProperty<Output = Ordering> + 'a>> {
|
) -> Option<Box<dyn TemplateProperty<Output = Ordering> + 'a>> {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(CoreTemplatePropertyKind::Integer(lhs), CoreTemplatePropertyKind::Integer(rhs)) => {
|
(CoreTemplatePropertyKind::Integer(lhs), CoreTemplatePropertyKind::Integer(rhs)) => {
|
||||||
Some(Box::new((lhs, rhs).map(|(l, r)| l.cmp(&r))))
|
Some((lhs, rhs).map(|(l, r)| l.cmp(&r)).into_dyn())
|
||||||
}
|
}
|
||||||
(CoreTemplatePropertyKind::String(_), _) => None,
|
(CoreTemplatePropertyKind::String(_), _) => None,
|
||||||
(CoreTemplatePropertyKind::StringList(_), _) => None,
|
(CoreTemplatePropertyKind::StringList(_), _) => None,
|
||||||
@ -529,14 +529,8 @@ impl<'a, L: TemplateLanguage<'a> + ?Sized> CoreTemplateBuildFnTable<'a, L> {
|
|||||||
let type_name = "Integer";
|
let type_name = "Integer";
|
||||||
let table = &self.integer_methods;
|
let table = &self.integer_methods;
|
||||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||||
let inner_property = property.try_unwrap(type_name);
|
let inner_property = property.try_unwrap(type_name).into_dyn();
|
||||||
build(
|
build(language, diagnostics, build_ctx, inner_property, function)
|
||||||
language,
|
|
||||||
diagnostics,
|
|
||||||
build_ctx,
|
|
||||||
Box::new(inner_property),
|
|
||||||
function,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
CoreTemplatePropertyKind::ConfigValue(property) => {
|
CoreTemplatePropertyKind::ConfigValue(property) => {
|
||||||
let table = &self.config_value_methods;
|
let table = &self.config_value_methods;
|
||||||
@ -1394,7 +1388,7 @@ where
|
|||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
});
|
});
|
||||||
Ok(wrap_list(Box::new(out_property)))
|
Ok(wrap_list(out_property.into_dyn()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds expression that extracts iterable property and applies template to
|
/// Builds expression that extracts iterable property and applies template to
|
||||||
@ -1888,7 +1882,7 @@ pub fn expect_isize_expression<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||||||
) -> TemplateParseResult<Box<dyn TemplateProperty<Output = isize> + 'a>> {
|
) -> TemplateParseResult<Box<dyn TemplateProperty<Output = isize> + 'a>> {
|
||||||
let i64_property = expect_integer_expression(language, diagnostics, build_ctx, node)?;
|
let i64_property = expect_integer_expression(language, diagnostics, build_ctx, node)?;
|
||||||
let isize_property = i64_property.and_then(|v| Ok(isize::try_from(v)?));
|
let isize_property = i64_property.and_then(|v| Ok(isize::try_from(v)?));
|
||||||
Ok(Box::new(isize_property))
|
Ok(isize_property.into_dyn())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If the given expression `node` is of `Integer` type, converts it to `usize`.
|
/// If the given expression `node` is of `Integer` type, converts it to `usize`.
|
||||||
@ -1900,7 +1894,7 @@ pub fn expect_usize_expression<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||||||
) -> TemplateParseResult<Box<dyn TemplateProperty<Output = usize> + 'a>> {
|
) -> TemplateParseResult<Box<dyn TemplateProperty<Output = usize> + 'a>> {
|
||||||
let i64_property = expect_integer_expression(language, diagnostics, build_ctx, node)?;
|
let i64_property = expect_integer_expression(language, diagnostics, build_ctx, node)?;
|
||||||
let usize_property = i64_property.and_then(|v| Ok(usize::try_from(v)?));
|
let usize_property = i64_property.and_then(|v| Ok(usize::try_from(v)?));
|
||||||
Ok(Box::new(usize_property))
|
Ok(usize_property.into_dyn())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect_plain_text_expression<'a, L: TemplateLanguage<'a> + ?Sized>(
|
pub fn expect_plain_text_expression<'a, L: TemplateLanguage<'a> + ?Sized>(
|
||||||
|
@ -435,6 +435,14 @@ pub trait TemplatePropertyExt: TemplateProperty {
|
|||||||
{
|
{
|
||||||
Box::new(FormattablePropertyTemplate::new(self))
|
Box::new(FormattablePropertyTemplate::new(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts this property into boxed trait object.
|
||||||
|
fn into_dyn<'a>(self) -> Box<dyn TemplateProperty<Output = Self::Output> + 'a>
|
||||||
|
where
|
||||||
|
Self: Sized + 'a,
|
||||||
|
{
|
||||||
|
Box::new(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: TemplateProperty + ?Sized> TemplatePropertyExt for P {}
|
impl<P: TemplateProperty + ?Sized> TemplatePropertyExt for P {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user