mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-18 10:07:28 +00:00
templater: remove redundant TemplateProperty wrapping from method chaining
TemplateFunction takes a property and a function to apply to the property value. That's exactly what a method call does.
This commit is contained in:
parent
4e7430a81a
commit
96f4d8798c
3 changed files with 62 additions and 85 deletions
|
@ -30,7 +30,8 @@ use crate::template_parser::{
|
|||
TemplateLanguage, TemplateParseError, TemplateParseResult,
|
||||
};
|
||||
use crate::templater::{
|
||||
self, IntoTemplate, PlainTextFormattedProperty, Template, TemplateProperty, TemplatePropertyFn,
|
||||
self, IntoTemplate, PlainTextFormattedProperty, Template, TemplateFunction, TemplateProperty,
|
||||
TemplatePropertyFn,
|
||||
};
|
||||
|
||||
struct CommitTemplateLanguage<'repo, 'b> {
|
||||
|
@ -369,21 +370,17 @@ fn build_commit_or_change_id_method<'repo>(
|
|||
let property = match function.name {
|
||||
"short" => {
|
||||
let len_property = parse_optional_integer(function)?;
|
||||
language.wrap_string(template_parser::chain_properties(
|
||||
language.wrap_string(Box::new(TemplateFunction::new(
|
||||
(self_property, len_property),
|
||||
TemplatePropertyFn(|(id, len): &(CommitOrChangeId, Option<i64>)| {
|
||||
id.short(len.and_then(|l| l.try_into().ok()).unwrap_or(12))
|
||||
}),
|
||||
))
|
||||
|(id, len)| id.short(len.and_then(|l| l.try_into().ok()).unwrap_or(12)),
|
||||
)))
|
||||
}
|
||||
"shortest" => {
|
||||
let len_property = parse_optional_integer(function)?;
|
||||
language.wrap_shortest_id_prefix(template_parser::chain_properties(
|
||||
language.wrap_shortest_id_prefix(Box::new(TemplateFunction::new(
|
||||
(self_property, len_property),
|
||||
TemplatePropertyFn(|(id, len): &(CommitOrChangeId, Option<i64>)| {
|
||||
id.shortest(len.and_then(|l| l.try_into().ok()).unwrap_or(0))
|
||||
}),
|
||||
))
|
||||
|(id, len)| id.shortest(len.and_then(|l| l.try_into().ok()).unwrap_or(0)),
|
||||
)))
|
||||
}
|
||||
_ => {
|
||||
return Err(TemplateParseError::no_such_method(
|
||||
|
@ -430,31 +427,25 @@ fn build_shortest_id_prefix_method<'repo>(
|
|||
let property = match function.name {
|
||||
"prefix" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_string(template_parser::chain_properties(
|
||||
self_property,
|
||||
TemplatePropertyFn(|id: &ShortestIdPrefix| id.prefix.clone()),
|
||||
))
|
||||
language.wrap_string(Box::new(TemplateFunction::new(self_property, |id| {
|
||||
id.prefix
|
||||
})))
|
||||
}
|
||||
"rest" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_string(template_parser::chain_properties(
|
||||
self_property,
|
||||
TemplatePropertyFn(|id: &ShortestIdPrefix| id.rest.clone()),
|
||||
))
|
||||
language.wrap_string(Box::new(TemplateFunction::new(self_property, |id| id.rest)))
|
||||
}
|
||||
"upper" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_shortest_id_prefix(template_parser::chain_properties(
|
||||
self_property,
|
||||
TemplatePropertyFn(|id: &ShortestIdPrefix| id.to_upper()),
|
||||
))
|
||||
language.wrap_shortest_id_prefix(Box::new(TemplateFunction::new(self_property, |id| {
|
||||
id.to_upper()
|
||||
})))
|
||||
}
|
||||
"lower" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_shortest_id_prefix(template_parser::chain_properties(
|
||||
self_property,
|
||||
TemplatePropertyFn(|id: &ShortestIdPrefix| id.to_lower()),
|
||||
))
|
||||
language.wrap_shortest_id_prefix(Box::new(TemplateFunction::new(self_property, |id| {
|
||||
id.to_lower()
|
||||
})))
|
||||
}
|
||||
_ => {
|
||||
return Err(TemplateParseError::no_such_method(
|
||||
|
|
|
@ -25,8 +25,8 @@ use crate::template_parser::{
|
|||
TemplateLanguage, TemplateParseError, TemplateParseResult,
|
||||
};
|
||||
use crate::templater::{
|
||||
IntoTemplate, PlainTextFormattedProperty, Template, TemplateProperty, TemplatePropertyFn,
|
||||
TimestampRange,
|
||||
IntoTemplate, PlainTextFormattedProperty, Template, TemplateFunction, TemplateProperty,
|
||||
TemplatePropertyFn, TimestampRange,
|
||||
};
|
||||
|
||||
struct OperationTemplateLanguage<'b> {
|
||||
|
@ -168,14 +168,14 @@ fn build_operation_id_method(
|
|||
let len_property = len_node
|
||||
.map(|node| template_parser::expect_integer_expression(language, node))
|
||||
.transpose()?;
|
||||
language.wrap_string(template_parser::chain_properties(
|
||||
language.wrap_string(Box::new(TemplateFunction::new(
|
||||
(self_property, len_property),
|
||||
TemplatePropertyFn(|(id, len): &(OperationId, Option<i64>)| {
|
||||
|(id, len)| {
|
||||
let mut hex = id.hex();
|
||||
hex.truncate(len.and_then(|l| l.try_into().ok()).unwrap_or(12));
|
||||
hex
|
||||
}),
|
||||
))
|
||||
},
|
||||
)))
|
||||
}
|
||||
_ => return Err(TemplateParseError::no_such_method("OperationId", function)),
|
||||
};
|
||||
|
|
|
@ -27,7 +27,7 @@ use thiserror::Error;
|
|||
use crate::templater::{
|
||||
ConditionalTemplate, IndentTemplate, IntoTemplate, LabelTemplate, ListTemplate, Literal,
|
||||
PlainTextFormattedProperty, SeparateTemplate, Template, TemplateFunction, TemplateProperty,
|
||||
TemplatePropertyFn, TimestampRange,
|
||||
TimestampRange,
|
||||
};
|
||||
use crate::time_util;
|
||||
|
||||
|
@ -848,15 +848,6 @@ fn build_method_call<'a, L: TemplateLanguage<'a>>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn chain_properties<'a, I: 'a, J: 'a, O: 'a>(
|
||||
first: impl TemplateProperty<I, Output = J> + 'a,
|
||||
second: impl TemplateProperty<J, Output = O> + 'a,
|
||||
) -> Box<dyn TemplateProperty<I, Output = O> + 'a> {
|
||||
Box::new(TemplateFunction::new(first, move |value| {
|
||||
second.extract(&value)
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn build_core_method<'a, L: TemplateLanguage<'a>>(
|
||||
language: &L,
|
||||
property: CoreTemplatePropertyKind<'a, L::Context>,
|
||||
|
@ -894,33 +885,28 @@ fn build_string_method<'a, L: TemplateLanguage<'a>>(
|
|||
let [needle_node] = expect_exact_arguments(function)?;
|
||||
// TODO: or .try_into_string() to disable implicit type cast?
|
||||
let needle_property = build_expression(language, needle_node)?.into_plain_text();
|
||||
language.wrap_boolean(chain_properties(
|
||||
language.wrap_boolean(Box::new(TemplateFunction::new(
|
||||
(self_property, needle_property),
|
||||
TemplatePropertyFn(|(haystack, needle): &(String, String)| {
|
||||
haystack.contains(needle)
|
||||
}),
|
||||
))
|
||||
|(haystack, needle)| haystack.contains(&needle),
|
||||
)))
|
||||
}
|
||||
"first_line" => {
|
||||
expect_no_arguments(function)?;
|
||||
language.wrap_string(chain_properties(
|
||||
self_property,
|
||||
TemplatePropertyFn(|s: &String| s.lines().next().unwrap_or_default().to_string()),
|
||||
))
|
||||
language.wrap_string(Box::new(TemplateFunction::new(self_property, |s| {
|
||||
s.lines().next().unwrap_or_default().to_string()
|
||||
})))
|
||||
}
|
||||
"upper" => {
|
||||
expect_no_arguments(function)?;
|
||||
language.wrap_string(chain_properties(
|
||||
self_property,
|
||||
TemplatePropertyFn(|s: &String| s.to_uppercase()),
|
||||
))
|
||||
language.wrap_string(Box::new(TemplateFunction::new(self_property, |s| {
|
||||
s.to_uppercase()
|
||||
})))
|
||||
}
|
||||
"lower" => {
|
||||
expect_no_arguments(function)?;
|
||||
language.wrap_string(chain_properties(
|
||||
self_property,
|
||||
TemplatePropertyFn(|s: &String| s.to_lowercase()),
|
||||
))
|
||||
language.wrap_string(Box::new(TemplateFunction::new(self_property, |s| {
|
||||
s.to_lowercase()
|
||||
})))
|
||||
}
|
||||
_ => return Err(TemplateParseError::no_such_method("String", function)),
|
||||
};
|
||||
|
@ -951,34 +937,34 @@ fn build_signature_method<'a, L: TemplateLanguage<'a>>(
|
|||
let property = match function.name {
|
||||
"name" => {
|
||||
expect_no_arguments(function)?;
|
||||
language.wrap_string(chain_properties(
|
||||
language.wrap_string(Box::new(TemplateFunction::new(
|
||||
self_property,
|
||||
TemplatePropertyFn(|signature: &Signature| signature.name.clone()),
|
||||
))
|
||||
|signature| signature.name,
|
||||
)))
|
||||
}
|
||||
"email" => {
|
||||
expect_no_arguments(function)?;
|
||||
language.wrap_string(chain_properties(
|
||||
language.wrap_string(Box::new(TemplateFunction::new(
|
||||
self_property,
|
||||
TemplatePropertyFn(|signature: &Signature| signature.email.clone()),
|
||||
))
|
||||
|signature| signature.email,
|
||||
)))
|
||||
}
|
||||
"username" => {
|
||||
expect_no_arguments(function)?;
|
||||
language.wrap_string(chain_properties(
|
||||
language.wrap_string(Box::new(TemplateFunction::new(
|
||||
self_property,
|
||||
TemplatePropertyFn(|signature: &Signature| {
|
||||
|signature| {
|
||||
let (username, _) = split_email(&signature.email);
|
||||
username.to_owned()
|
||||
}),
|
||||
))
|
||||
},
|
||||
)))
|
||||
}
|
||||
"timestamp" => {
|
||||
expect_no_arguments(function)?;
|
||||
language.wrap_timestamp(chain_properties(
|
||||
language.wrap_timestamp(Box::new(TemplateFunction::new(
|
||||
self_property,
|
||||
TemplatePropertyFn(|signature: &Signature| signature.timestamp.clone()),
|
||||
))
|
||||
|signature| signature.timestamp,
|
||||
)))
|
||||
}
|
||||
_ => return Err(TemplateParseError::no_such_method("Signature", function)),
|
||||
};
|
||||
|
@ -993,10 +979,10 @@ fn build_timestamp_method<'a, L: TemplateLanguage<'a>>(
|
|||
let property = match function.name {
|
||||
"ago" => {
|
||||
expect_no_arguments(function)?;
|
||||
language.wrap_string(chain_properties(
|
||||
language.wrap_string(Box::new(TemplateFunction::new(
|
||||
self_property,
|
||||
TemplatePropertyFn(time_util::format_timestamp_relative_to_now),
|
||||
))
|
||||
|timestamp| time_util::format_timestamp_relative_to_now(×tamp),
|
||||
)))
|
||||
}
|
||||
_ => return Err(TemplateParseError::no_such_method("Timestamp", function)),
|
||||
};
|
||||
|
@ -1011,24 +997,24 @@ fn build_timestamp_range_method<'a, L: TemplateLanguage<'a>>(
|
|||
let property = match function.name {
|
||||
"start" => {
|
||||
expect_no_arguments(function)?;
|
||||
language.wrap_timestamp(chain_properties(
|
||||
language.wrap_timestamp(Box::new(TemplateFunction::new(
|
||||
self_property,
|
||||
TemplatePropertyFn(|time_range: &TimestampRange| time_range.start.clone()),
|
||||
))
|
||||
|time_range| time_range.start,
|
||||
)))
|
||||
}
|
||||
"end" => {
|
||||
expect_no_arguments(function)?;
|
||||
language.wrap_timestamp(chain_properties(
|
||||
language.wrap_timestamp(Box::new(TemplateFunction::new(
|
||||
self_property,
|
||||
TemplatePropertyFn(|time_range: &TimestampRange| time_range.end.clone()),
|
||||
))
|
||||
|time_range| time_range.end,
|
||||
)))
|
||||
}
|
||||
"duration" => {
|
||||
expect_no_arguments(function)?;
|
||||
language.wrap_string(chain_properties(
|
||||
language.wrap_string(Box::new(TemplateFunction::new(
|
||||
self_property,
|
||||
TemplatePropertyFn(TimestampRange::duration),
|
||||
))
|
||||
|time_range| time_range.duration(),
|
||||
)))
|
||||
}
|
||||
_ => {
|
||||
return Err(TemplateParseError::no_such_method(
|
||||
|
|
Loading…
Reference in a new issue