forked from mirrors/jj
templater: parameterize property type
This commit is contained in:
parent
907bddaf1e
commit
5474268d22
1 changed files with 53 additions and 55 deletions
|
@ -584,47 +584,43 @@ fn expand_aliases<'i>(
|
||||||
/// Callbacks to build language-specific evaluation objects from AST nodes.
|
/// Callbacks to build language-specific evaluation objects from AST nodes.
|
||||||
trait TemplateLanguage<'a> {
|
trait TemplateLanguage<'a> {
|
||||||
type Context: 'a;
|
type Context: 'a;
|
||||||
// TODO: type Property;
|
type Property: IntoTemplateProperty<'a, Self::Context>;
|
||||||
|
|
||||||
fn wrap_string(
|
fn wrap_string(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = String> + 'a>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = String> + 'a>,
|
||||||
) -> Property<'a, Self::Context>;
|
) -> Self::Property;
|
||||||
fn wrap_boolean(
|
fn wrap_boolean(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = bool> + 'a>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = bool> + 'a>,
|
||||||
) -> Property<'a, Self::Context>;
|
) -> Self::Property;
|
||||||
fn wrap_integer(
|
fn wrap_integer(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = i64> + 'a>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = i64> + 'a>,
|
||||||
) -> Property<'a, Self::Context>;
|
) -> Self::Property;
|
||||||
fn wrap_commit_or_change_id(
|
fn wrap_commit_or_change_id(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = CommitOrChangeId<'a>> + 'a>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = CommitOrChangeId<'a>> + 'a>,
|
||||||
) -> Property<'a, Self::Context>;
|
) -> Self::Property;
|
||||||
fn wrap_shortest_id_prefix(
|
fn wrap_shortest_id_prefix(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = ShortestIdPrefix> + 'a>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = ShortestIdPrefix> + 'a>,
|
||||||
) -> Property<'a, Self::Context>;
|
) -> Self::Property;
|
||||||
fn wrap_signature(
|
fn wrap_signature(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = Signature> + 'a>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = Signature> + 'a>,
|
||||||
) -> Property<'a, Self::Context>;
|
) -> Self::Property;
|
||||||
fn wrap_timestamp(
|
fn wrap_timestamp(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = Timestamp> + 'a>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = Timestamp> + 'a>,
|
||||||
) -> Property<'a, Self::Context>;
|
) -> Self::Property;
|
||||||
|
|
||||||
fn build_keyword(
|
fn build_keyword(&self, name: &str, span: pest::Span) -> TemplateParseResult<Self::Property>;
|
||||||
&self,
|
|
||||||
name: &str,
|
|
||||||
span: pest::Span,
|
|
||||||
) -> TemplateParseResult<Property<'a, Self::Context>>;
|
|
||||||
fn build_method(
|
fn build_method(
|
||||||
&self,
|
&self,
|
||||||
property: Property<'a, Self::Context>,
|
property: Self::Property,
|
||||||
function: &FunctionCallNode,
|
function: &FunctionCallNode,
|
||||||
) -> TemplateParseResult<Property<'a, Self::Context>>;
|
) -> TemplateParseResult<Self::Property>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provides access to basic template property types.
|
/// Provides access to basic template property types.
|
||||||
|
@ -689,12 +685,12 @@ impl<'a, I: 'a> IntoTemplateProperty<'a, I> for Property<'a, I> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Expression<'a, C> {
|
enum Expression<'a, C, P> {
|
||||||
Property(Property<'a, C>, Vec<String>),
|
Property(P, Vec<String>),
|
||||||
Template(Box<dyn Template<C> + 'a>),
|
Template(Box<dyn Template<C> + 'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, C: 'a> Expression<'a, C> {
|
impl<'a, C: 'a, P: IntoTemplateProperty<'a, C>> Expression<'a, C, P> {
|
||||||
fn try_into_boolean(self) -> Option<Box<dyn TemplateProperty<C, Output = bool> + 'a>> {
|
fn try_into_boolean(self) -> Option<Box<dyn TemplateProperty<C, Output = bool> + 'a>> {
|
||||||
match self {
|
match self {
|
||||||
Expression::Property(property, _) => property.try_into_boolean(),
|
Expression::Property(property, _) => property.try_into_boolean(),
|
||||||
|
@ -800,7 +796,7 @@ fn split_email(email: &str) -> (&str, Option<&str>) {
|
||||||
fn build_method_call<'a, L: TemplateLanguage<'a>>(
|
fn build_method_call<'a, L: TemplateLanguage<'a>>(
|
||||||
language: &L,
|
language: &L,
|
||||||
method: &MethodCallNode,
|
method: &MethodCallNode,
|
||||||
) -> TemplateParseResult<Expression<'a, L::Context>> {
|
) -> TemplateParseResult<Expression<'a, L::Context, L::Property>> {
|
||||||
match build_expression(language, &method.object)? {
|
match build_expression(language, &method.object)? {
|
||||||
Expression::Property(property, mut labels) => {
|
Expression::Property(property, mut labels) => {
|
||||||
let property = language.build_method(property, &method.function)?;
|
let property = language.build_method(property, &method.function)?;
|
||||||
|
@ -827,7 +823,7 @@ fn build_core_method<'a, L: TemplateLanguage<'a>>(
|
||||||
language: &L,
|
language: &L,
|
||||||
property: Property<'a, L::Context>,
|
property: Property<'a, L::Context>,
|
||||||
function: &FunctionCallNode,
|
function: &FunctionCallNode,
|
||||||
) -> TemplateParseResult<Property<'a, L::Context>> {
|
) -> TemplateParseResult<L::Property> {
|
||||||
match property {
|
match property {
|
||||||
Property::String(property) => build_string_method(language, property, function),
|
Property::String(property) => build_string_method(language, property, function),
|
||||||
Property::Boolean(property) => build_boolean_method(language, property, function),
|
Property::Boolean(property) => build_boolean_method(language, property, function),
|
||||||
|
@ -847,7 +843,7 @@ fn build_string_method<'a, L: TemplateLanguage<'a>>(
|
||||||
language: &L,
|
language: &L,
|
||||||
self_property: impl TemplateProperty<L::Context, Output = String> + 'a,
|
self_property: impl TemplateProperty<L::Context, Output = String> + 'a,
|
||||||
function: &FunctionCallNode,
|
function: &FunctionCallNode,
|
||||||
) -> TemplateParseResult<Property<'a, L::Context>> {
|
) -> TemplateParseResult<L::Property> {
|
||||||
let property = match function.name {
|
let property = match function.name {
|
||||||
"contains" => {
|
"contains" => {
|
||||||
let [needle_node] = expect_exact_arguments(function)?;
|
let [needle_node] = expect_exact_arguments(function)?;
|
||||||
|
@ -876,7 +872,7 @@ fn build_boolean_method<'a, L: TemplateLanguage<'a>>(
|
||||||
_language: &L,
|
_language: &L,
|
||||||
_self_property: impl TemplateProperty<L::Context, Output = bool> + 'a,
|
_self_property: impl TemplateProperty<L::Context, Output = bool> + 'a,
|
||||||
function: &FunctionCallNode,
|
function: &FunctionCallNode,
|
||||||
) -> TemplateParseResult<Property<'a, L::Context>> {
|
) -> TemplateParseResult<L::Property> {
|
||||||
Err(TemplateParseError::no_such_method("Boolean", function))
|
Err(TemplateParseError::no_such_method("Boolean", function))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,7 +880,7 @@ fn build_integer_method<'a, L: TemplateLanguage<'a>>(
|
||||||
_language: &L,
|
_language: &L,
|
||||||
_self_property: impl TemplateProperty<L::Context, Output = i64> + 'a,
|
_self_property: impl TemplateProperty<L::Context, Output = i64> + 'a,
|
||||||
function: &FunctionCallNode,
|
function: &FunctionCallNode,
|
||||||
) -> TemplateParseResult<Property<'a, L::Context>> {
|
) -> TemplateParseResult<L::Property> {
|
||||||
Err(TemplateParseError::no_such_method("Integer", function))
|
Err(TemplateParseError::no_such_method("Integer", function))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -892,7 +888,7 @@ fn build_commit_or_change_id_method<'a, L: TemplateLanguage<'a>>(
|
||||||
language: &L,
|
language: &L,
|
||||||
self_property: impl TemplateProperty<L::Context, Output = CommitOrChangeId<'a>> + 'a,
|
self_property: impl TemplateProperty<L::Context, Output = CommitOrChangeId<'a>> + 'a,
|
||||||
function: &FunctionCallNode,
|
function: &FunctionCallNode,
|
||||||
) -> TemplateParseResult<Property<'a, L::Context>> {
|
) -> TemplateParseResult<L::Property> {
|
||||||
let parse_optional_integer = |function| -> Result<Option<_>, TemplateParseError> {
|
let parse_optional_integer = |function| -> Result<Option<_>, TemplateParseError> {
|
||||||
let ([], [len_node]) = expect_arguments(function)?;
|
let ([], [len_node]) = expect_arguments(function)?;
|
||||||
len_node
|
len_node
|
||||||
|
@ -938,7 +934,7 @@ fn build_shortest_id_prefix_method<'a, L: TemplateLanguage<'a>>(
|
||||||
language: &L,
|
language: &L,
|
||||||
self_property: impl TemplateProperty<L::Context, Output = ShortestIdPrefix> + 'a,
|
self_property: impl TemplateProperty<L::Context, Output = ShortestIdPrefix> + 'a,
|
||||||
function: &FunctionCallNode,
|
function: &FunctionCallNode,
|
||||||
) -> TemplateParseResult<Property<'a, L::Context>> {
|
) -> TemplateParseResult<L::Property> {
|
||||||
let property = match function.name {
|
let property = match function.name {
|
||||||
"prefix" => {
|
"prefix" => {
|
||||||
expect_no_arguments(function)?;
|
expect_no_arguments(function)?;
|
||||||
|
@ -968,7 +964,7 @@ fn build_signature_method<'a, L: TemplateLanguage<'a>>(
|
||||||
language: &L,
|
language: &L,
|
||||||
self_property: impl TemplateProperty<L::Context, Output = Signature> + 'a,
|
self_property: impl TemplateProperty<L::Context, Output = Signature> + 'a,
|
||||||
function: &FunctionCallNode,
|
function: &FunctionCallNode,
|
||||||
) -> TemplateParseResult<Property<'a, L::Context>> {
|
) -> TemplateParseResult<L::Property> {
|
||||||
let property = match function.name {
|
let property = match function.name {
|
||||||
"name" => {
|
"name" => {
|
||||||
expect_no_arguments(function)?;
|
expect_no_arguments(function)?;
|
||||||
|
@ -1010,7 +1006,7 @@ fn build_timestamp_method<'a, L: TemplateLanguage<'a>>(
|
||||||
language: &L,
|
language: &L,
|
||||||
self_property: impl TemplateProperty<L::Context, Output = Timestamp> + 'a,
|
self_property: impl TemplateProperty<L::Context, Output = Timestamp> + 'a,
|
||||||
function: &FunctionCallNode,
|
function: &FunctionCallNode,
|
||||||
) -> TemplateParseResult<Property<'a, L::Context>> {
|
) -> TemplateParseResult<L::Property> {
|
||||||
let property = match function.name {
|
let property = match function.name {
|
||||||
"ago" => {
|
"ago" => {
|
||||||
expect_no_arguments(function)?;
|
expect_no_arguments(function)?;
|
||||||
|
@ -1027,7 +1023,7 @@ fn build_timestamp_method<'a, L: TemplateLanguage<'a>>(
|
||||||
fn build_global_function<'a, L: TemplateLanguage<'a>>(
|
fn build_global_function<'a, L: TemplateLanguage<'a>>(
|
||||||
language: &L,
|
language: &L,
|
||||||
function: &FunctionCallNode,
|
function: &FunctionCallNode,
|
||||||
) -> TemplateParseResult<Expression<'a, L::Context>> {
|
) -> TemplateParseResult<Expression<'a, L::Context, L::Property>> {
|
||||||
let expression = match function.name {
|
let expression = match function.name {
|
||||||
"label" => {
|
"label" => {
|
||||||
let [label_node, content_node] = expect_exact_arguments(function)?;
|
let [label_node, content_node] = expect_exact_arguments(function)?;
|
||||||
|
@ -1125,7 +1121,7 @@ fn build_commit_keyword<'a>(
|
||||||
fn build_expression<'a, L: TemplateLanguage<'a>>(
|
fn build_expression<'a, L: TemplateLanguage<'a>>(
|
||||||
language: &L,
|
language: &L,
|
||||||
node: &ExpressionNode,
|
node: &ExpressionNode,
|
||||||
) -> TemplateParseResult<Expression<'a, L::Context>> {
|
) -> TemplateParseResult<Expression<'a, L::Context, L::Property>> {
|
||||||
match &node.kind {
|
match &node.kind {
|
||||||
ExpressionKind::Identifier(name) => {
|
ExpressionKind::Identifier(name) => {
|
||||||
let property = language.build_keyword(name, node.span)?;
|
let property = language.build_keyword(name, node.span)?;
|
||||||
|
@ -1162,64 +1158,61 @@ struct CommitTemplateLanguage<'a, 'b> {
|
||||||
|
|
||||||
impl<'a> TemplateLanguage<'a> for CommitTemplateLanguage<'a, '_> {
|
impl<'a> TemplateLanguage<'a> for CommitTemplateLanguage<'a, '_> {
|
||||||
type Context = Commit;
|
type Context = Commit;
|
||||||
|
type Property = Property<'a, Commit>;
|
||||||
|
|
||||||
// TODO: maybe generate wrap_<type>() by macro?
|
// TODO: maybe generate wrap_<type>() by macro?
|
||||||
fn wrap_string(
|
fn wrap_string(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = String> + 'a>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = String> + 'a>,
|
||||||
) -> Property<'a, Self::Context> {
|
) -> Self::Property {
|
||||||
Property::String(property)
|
Property::String(property)
|
||||||
}
|
}
|
||||||
fn wrap_boolean(
|
fn wrap_boolean(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = bool> + 'a>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = bool> + 'a>,
|
||||||
) -> Property<'a, Self::Context> {
|
) -> Self::Property {
|
||||||
Property::Boolean(property)
|
Property::Boolean(property)
|
||||||
}
|
}
|
||||||
fn wrap_integer(
|
fn wrap_integer(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = i64> + 'a>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = i64> + 'a>,
|
||||||
) -> Property<'a, Self::Context> {
|
) -> Self::Property {
|
||||||
Property::Integer(property)
|
Property::Integer(property)
|
||||||
}
|
}
|
||||||
fn wrap_commit_or_change_id(
|
fn wrap_commit_or_change_id(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = CommitOrChangeId<'a>> + 'a>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = CommitOrChangeId<'a>> + 'a>,
|
||||||
) -> Property<'a, Self::Context> {
|
) -> Self::Property {
|
||||||
Property::CommitOrChangeId(property)
|
Property::CommitOrChangeId(property)
|
||||||
}
|
}
|
||||||
fn wrap_shortest_id_prefix(
|
fn wrap_shortest_id_prefix(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = ShortestIdPrefix> + 'a>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = ShortestIdPrefix> + 'a>,
|
||||||
) -> Property<'a, Self::Context> {
|
) -> Self::Property {
|
||||||
Property::ShortestIdPrefix(property)
|
Property::ShortestIdPrefix(property)
|
||||||
}
|
}
|
||||||
fn wrap_signature(
|
fn wrap_signature(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = Signature> + 'a>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = Signature> + 'a>,
|
||||||
) -> Property<'a, Self::Context> {
|
) -> Self::Property {
|
||||||
Property::Signature(property)
|
Property::Signature(property)
|
||||||
}
|
}
|
||||||
fn wrap_timestamp(
|
fn wrap_timestamp(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = Timestamp> + 'a>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = Timestamp> + 'a>,
|
||||||
) -> Property<'a, Self::Context> {
|
) -> Self::Property {
|
||||||
Property::Timestamp(property)
|
Property::Timestamp(property)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_keyword(
|
fn build_keyword(&self, name: &str, span: pest::Span) -> TemplateParseResult<Self::Property> {
|
||||||
&self,
|
|
||||||
name: &str,
|
|
||||||
span: pest::Span,
|
|
||||||
) -> TemplateParseResult<Property<'a, Self::Context>> {
|
|
||||||
build_commit_keyword(self, name, span)
|
build_commit_keyword(self, name, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_method(
|
fn build_method(
|
||||||
&self,
|
&self,
|
||||||
property: Property<'a, Self::Context>,
|
property: Self::Property,
|
||||||
function: &FunctionCallNode,
|
function: &FunctionCallNode,
|
||||||
) -> TemplateParseResult<Property<'a, Self::Context>> {
|
) -> TemplateParseResult<Self::Property> {
|
||||||
build_core_method(self, property, function)
|
build_core_method(self, property, function)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1245,23 +1238,24 @@ mod tests {
|
||||||
|
|
||||||
impl TemplateLanguage<'static> for MinimalTemplateLanguage {
|
impl TemplateLanguage<'static> for MinimalTemplateLanguage {
|
||||||
type Context = ();
|
type Context = ();
|
||||||
|
type Property = Property<'static, ()>;
|
||||||
|
|
||||||
fn wrap_string(
|
fn wrap_string(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = String> + 'static>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = String> + 'static>,
|
||||||
) -> Property<'static, Self::Context> {
|
) -> Self::Property {
|
||||||
Property::String(property)
|
Property::String(property)
|
||||||
}
|
}
|
||||||
fn wrap_boolean(
|
fn wrap_boolean(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = bool> + 'static>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = bool> + 'static>,
|
||||||
) -> Property<'static, Self::Context> {
|
) -> Self::Property {
|
||||||
Property::Boolean(property)
|
Property::Boolean(property)
|
||||||
}
|
}
|
||||||
fn wrap_integer(
|
fn wrap_integer(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = i64> + 'static>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = i64> + 'static>,
|
||||||
) -> Property<'static, Self::Context> {
|
) -> Self::Property {
|
||||||
Property::Integer(property)
|
Property::Integer(property)
|
||||||
}
|
}
|
||||||
fn wrap_commit_or_change_id(
|
fn wrap_commit_or_change_id(
|
||||||
|
@ -1269,25 +1263,25 @@ mod tests {
|
||||||
property: Box<
|
property: Box<
|
||||||
dyn TemplateProperty<Self::Context, Output = CommitOrChangeId<'static>> + 'static,
|
dyn TemplateProperty<Self::Context, Output = CommitOrChangeId<'static>> + 'static,
|
||||||
>,
|
>,
|
||||||
) -> Property<'static, Self::Context> {
|
) -> Self::Property {
|
||||||
Property::CommitOrChangeId(property)
|
Property::CommitOrChangeId(property)
|
||||||
}
|
}
|
||||||
fn wrap_shortest_id_prefix(
|
fn wrap_shortest_id_prefix(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = ShortestIdPrefix> + 'static>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = ShortestIdPrefix> + 'static>,
|
||||||
) -> Property<'static, Self::Context> {
|
) -> Self::Property {
|
||||||
Property::ShortestIdPrefix(property)
|
Property::ShortestIdPrefix(property)
|
||||||
}
|
}
|
||||||
fn wrap_signature(
|
fn wrap_signature(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = Signature> + 'static>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = Signature> + 'static>,
|
||||||
) -> Property<'static, Self::Context> {
|
) -> Self::Property {
|
||||||
Property::Signature(property)
|
Property::Signature(property)
|
||||||
}
|
}
|
||||||
fn wrap_timestamp(
|
fn wrap_timestamp(
|
||||||
&self,
|
&self,
|
||||||
property: Box<dyn TemplateProperty<Self::Context, Output = Timestamp> + 'static>,
|
property: Box<dyn TemplateProperty<Self::Context, Output = Timestamp> + 'static>,
|
||||||
) -> Property<'static, Self::Context> {
|
) -> Self::Property {
|
||||||
Property::Timestamp(property)
|
Property::Timestamp(property)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1295,15 +1289,15 @@ mod tests {
|
||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
span: pest::Span,
|
span: pest::Span,
|
||||||
) -> TemplateParseResult<Property<'static, Self::Context>> {
|
) -> TemplateParseResult<Self::Property> {
|
||||||
Err(TemplateParseError::no_such_keyword(name, span))
|
Err(TemplateParseError::no_such_keyword(name, span))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_method(
|
fn build_method(
|
||||||
&self,
|
&self,
|
||||||
property: Property<'static, Self::Context>,
|
property: Self::Property,
|
||||||
function: &FunctionCallNode,
|
function: &FunctionCallNode,
|
||||||
) -> TemplateParseResult<Property<'static, Self::Context>> {
|
) -> TemplateParseResult<Self::Property> {
|
||||||
build_core_method(self, property, function)
|
build_core_method(self, property, function)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1335,7 +1329,9 @@ mod tests {
|
||||||
WithTemplateAliasesMap(aliases_map)
|
WithTemplateAliasesMap(aliases_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse(template_text: &str) -> TemplateParseResult<Expression<'static, ()>> {
|
fn parse(
|
||||||
|
template_text: &str,
|
||||||
|
) -> TemplateParseResult<Expression<'static, (), Property<'static, ()>>> {
|
||||||
let node = parse_template(template_text)?;
|
let node = parse_template(template_text)?;
|
||||||
build_expression(&MinimalTemplateLanguage, &node)
|
build_expression(&MinimalTemplateLanguage, &node)
|
||||||
}
|
}
|
||||||
|
@ -1420,7 +1416,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_integer_literal() {
|
fn test_integer_literal() {
|
||||||
let extract = |x: Expression<()>| x.try_into_integer().unwrap().extract(&());
|
fn extract<'a>(x: Expression<'a, (), Property<'a, ()>>) -> i64 {
|
||||||
|
x.try_into_integer().unwrap().extract(&())
|
||||||
|
}
|
||||||
|
|
||||||
assert_eq!(extract(parse("0").unwrap()), 0);
|
assert_eq!(extract(parse("0").unwrap()), 0);
|
||||||
assert_eq!(extract(parse("(42)").unwrap()), 42);
|
assert_eq!(extract(parse("(42)").unwrap()), 42);
|
||||||
|
|
Loading…
Reference in a new issue