forked from mirrors/jj
templater: leverage TemplateProperty::map/and_then() helpers
This commit is contained in:
parent
a3d44485f4
commit
fad712811c
7 changed files with 144 additions and 215 deletions
|
@ -18,7 +18,7 @@ use jj_cli::commit_templater::{
|
|||
};
|
||||
use jj_cli::template_builder::TemplateLanguage;
|
||||
use jj_cli::template_parser::{self, TemplateParseError};
|
||||
use jj_cli::templater::{TemplateFunction, TemplatePropertyError};
|
||||
use jj_cli::templater::TemplatePropertyExt as _;
|
||||
use jj_lib::backend::CommitId;
|
||||
use jj_lib::commit::Commit;
|
||||
use jj_lib::extensions_map::ExtensionsMap;
|
||||
|
@ -39,14 +39,14 @@ fn num_digits_in_id(id: &CommitId) -> i64 {
|
|||
count
|
||||
}
|
||||
|
||||
fn num_char_in_id(commit: Commit, ch_match: char) -> Result<i64, TemplatePropertyError> {
|
||||
fn num_char_in_id(commit: Commit, ch_match: char) -> i64 {
|
||||
let mut count = 0;
|
||||
for ch in commit.id().hex().chars() {
|
||||
if ch == ch_match {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
Ok(count)
|
||||
count
|
||||
}
|
||||
|
||||
struct MostDigitsInId {
|
||||
|
@ -85,19 +85,18 @@ impl CommitTemplateLanguageExtension for HexCounter {
|
|||
.cache_extension::<MostDigitsInId>()
|
||||
.unwrap()
|
||||
.count(language.repo());
|
||||
Ok(L::wrap_boolean(TemplateFunction::new(
|
||||
property,
|
||||
move |commit| Ok(num_digits_in_id(commit.id()) == most_digits),
|
||||
)))
|
||||
Ok(L::wrap_boolean(property.map(move |commit| {
|
||||
num_digits_in_id(commit.id()) == most_digits
|
||||
})))
|
||||
},
|
||||
);
|
||||
table.commit_methods.insert(
|
||||
"num_digits_in_id",
|
||||
|_language, _build_context, property, call| {
|
||||
template_parser::expect_no_arguments(call)?;
|
||||
Ok(L::wrap_integer(TemplateFunction::new(property, |commit| {
|
||||
Ok(num_digits_in_id(commit.id()))
|
||||
})))
|
||||
Ok(L::wrap_integer(
|
||||
property.map(|commit| num_digits_in_id(commit.id())),
|
||||
))
|
||||
},
|
||||
);
|
||||
table.commit_methods.insert(
|
||||
|
@ -116,10 +115,9 @@ impl CommitTemplateLanguageExtension for HexCounter {
|
|||
}
|
||||
})?;
|
||||
|
||||
Ok(L::wrap_integer(TemplateFunction::new(
|
||||
property,
|
||||
move |commit| num_char_in_id(commit, char_arg),
|
||||
)))
|
||||
Ok(L::wrap_integer(
|
||||
property.map(move |commit| num_char_in_id(commit, char_arg)),
|
||||
))
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ use jj_cli::operation_templater::{
|
|||
};
|
||||
use jj_cli::template_builder::TemplateLanguage;
|
||||
use jj_cli::template_parser::{self, TemplateParseError};
|
||||
use jj_cli::templater::{TemplateFunction, TemplatePropertyError};
|
||||
use jj_cli::templater::TemplatePropertyExt as _;
|
||||
use jj_lib::extensions_map::ExtensionsMap;
|
||||
use jj_lib::object_id::ObjectId;
|
||||
use jj_lib::op_store::OperationId;
|
||||
|
@ -36,14 +36,14 @@ fn num_digits_in_id(id: &OperationId) -> i64 {
|
|||
count
|
||||
}
|
||||
|
||||
fn num_char_in_id(operation: Operation, ch_match: char) -> Result<i64, TemplatePropertyError> {
|
||||
fn num_char_in_id(operation: Operation, ch_match: char) -> i64 {
|
||||
let mut count = 0;
|
||||
for ch in operation.id().hex().chars() {
|
||||
if ch == ch_match {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
Ok(count)
|
||||
count
|
||||
}
|
||||
|
||||
impl OperationTemplateLanguageExtension for HexCounter {
|
||||
|
@ -54,10 +54,9 @@ impl OperationTemplateLanguageExtension for HexCounter {
|
|||
"num_digits_in_id",
|
||||
|_language, _build_context, property, call| {
|
||||
template_parser::expect_no_arguments(call)?;
|
||||
Ok(L::wrap_integer(TemplateFunction::new(
|
||||
property,
|
||||
|operation| Ok(num_digits_in_id(operation.id())),
|
||||
)))
|
||||
Ok(L::wrap_integer(
|
||||
property.map(|operation| num_digits_in_id(operation.id())),
|
||||
))
|
||||
},
|
||||
);
|
||||
table.operation_methods.insert(
|
||||
|
@ -76,10 +75,9 @@ impl OperationTemplateLanguageExtension for HexCounter {
|
|||
}
|
||||
})?;
|
||||
|
||||
Ok(L::wrap_integer(TemplateFunction::new(
|
||||
property,
|
||||
move |operation| num_char_in_id(operation, char_arg),
|
||||
)))
|
||||
Ok(L::wrap_integer(
|
||||
property.map(move |operation| num_char_in_id(operation, char_arg)),
|
||||
))
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ use crate::command_error::{user_error, CommandError};
|
|||
use crate::config::{AnnotatedValue, ConfigSource};
|
||||
use crate::generic_templater::GenericTemplateLanguage;
|
||||
use crate::template_builder::TemplateLanguage as _;
|
||||
use crate::templater::{Template as _, TemplateFunction};
|
||||
use crate::templater::{Template as _, TemplatePropertyExt as _};
|
||||
use crate::ui::Ui;
|
||||
|
||||
#[derive(clap::Args, Clone, Debug)]
|
||||
|
@ -191,20 +191,16 @@ fn config_template_language() -> GenericTemplateLanguage<'static, AnnotatedValue
|
|||
let mut language = L::new();
|
||||
// "name" instead of "path" to avoid confusion with the source file path
|
||||
language.add_keyword("name", |self_property| {
|
||||
let out_property =
|
||||
TemplateFunction::new(self_property, |annotated| Ok(annotated.path.join(".")));
|
||||
let out_property = self_property.map(|annotated| annotated.path.join("."));
|
||||
Ok(L::wrap_string(out_property))
|
||||
});
|
||||
language.add_keyword("value", |self_property| {
|
||||
// TODO: would be nice if we can provide raw dynamically-typed value
|
||||
let out_property = TemplateFunction::new(self_property, |annotated| {
|
||||
Ok(serialize_config_value(&annotated.value))
|
||||
});
|
||||
let out_property = self_property.map(|annotated| serialize_config_value(&annotated.value));
|
||||
Ok(L::wrap_string(out_property))
|
||||
});
|
||||
language.add_keyword("overridden", |self_property| {
|
||||
let out_property =
|
||||
TemplateFunction::new(self_property, |annotated| Ok(annotated.is_overridden));
|
||||
let out_property = self_property.map(|annotated| annotated.is_overridden);
|
||||
Ok(L::wrap_boolean(out_property))
|
||||
});
|
||||
language
|
||||
|
|
|
@ -38,7 +38,8 @@ use crate::template_builder::{
|
|||
};
|
||||
use crate::template_parser::{self, FunctionCallNode, TemplateParseError, TemplateParseResult};
|
||||
use crate::templater::{
|
||||
self, IntoTemplate, PlainTextFormattedProperty, Template, TemplateFunction, TemplateProperty,
|
||||
self, IntoTemplate, PlainTextFormattedProperty, Template, TemplateProperty,
|
||||
TemplatePropertyExt as _,
|
||||
};
|
||||
use crate::{revset_util, text_util};
|
||||
|
||||
|
@ -236,15 +237,11 @@ impl<'repo> IntoTemplateProperty<'repo> for CommitTemplatePropertyKind<'repo> {
|
|||
CommitTemplatePropertyKind::Core(property) => property.try_into_boolean(),
|
||||
CommitTemplatePropertyKind::Commit(_) => None,
|
||||
CommitTemplatePropertyKind::CommitList(property) => {
|
||||
Some(Box::new(TemplateFunction::new(property, |l| {
|
||||
Ok(!l.is_empty())
|
||||
})))
|
||||
Some(Box::new(property.map(|l| !l.is_empty())))
|
||||
}
|
||||
CommitTemplatePropertyKind::RefName(_) => None,
|
||||
CommitTemplatePropertyKind::RefNameList(property) => {
|
||||
Some(Box::new(TemplateFunction::new(property, |l| {
|
||||
Ok(!l.is_empty())
|
||||
})))
|
||||
Some(Box::new(property.map(|l| !l.is_empty())))
|
||||
}
|
||||
CommitTemplatePropertyKind::CommitOrChangeId(_) => None,
|
||||
CommitTemplatePropertyKind::ShortestIdPrefix(_) => None,
|
||||
|
@ -377,9 +374,8 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
"description",
|
||||
|_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |commit| {
|
||||
Ok(text_util::complete_newline(commit.description()))
|
||||
});
|
||||
let out_property =
|
||||
self_property.map(|commit| text_util::complete_newline(commit.description()));
|
||||
Ok(L::wrap_string(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -387,9 +383,8 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
"change_id",
|
||||
|_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |commit| {
|
||||
Ok(CommitOrChangeId::Change(commit.change_id().to_owned()))
|
||||
});
|
||||
let out_property =
|
||||
self_property.map(|commit| CommitOrChangeId::Change(commit.change_id().to_owned()));
|
||||
Ok(L::wrap_commit_or_change_id(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -397,9 +392,8 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
"commit_id",
|
||||
|_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |commit| {
|
||||
Ok(CommitOrChangeId::Commit(commit.id().to_owned()))
|
||||
});
|
||||
let out_property =
|
||||
self_property.map(|commit| CommitOrChangeId::Commit(commit.id().to_owned()));
|
||||
Ok(L::wrap_commit_or_change_id(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -407,7 +401,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
"parents",
|
||||
|_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |commit| Ok(commit.parents()));
|
||||
let out_property = self_property.map(|commit| commit.parents());
|
||||
Ok(L::wrap_commit_list(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -415,8 +409,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
"author",
|
||||
|_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property =
|
||||
TemplateFunction::new(self_property, |commit| Ok(commit.author().clone()));
|
||||
let out_property = self_property.map(|commit| commit.author().clone());
|
||||
Ok(L::wrap_signature(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -424,8 +417,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
"committer",
|
||||
|_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property =
|
||||
TemplateFunction::new(self_property, |commit| Ok(commit.committer().clone()));
|
||||
let out_property = self_property.map(|commit| commit.committer().clone());
|
||||
Ok(L::wrap_signature(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -434,9 +426,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
|language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let repo = language.repo;
|
||||
let out_property = TemplateFunction::new(self_property, |commit| {
|
||||
Ok(extract_working_copies(repo, &commit))
|
||||
});
|
||||
let out_property = self_property.map(|commit| extract_working_copies(repo, &commit));
|
||||
Ok(L::wrap_string(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -446,8 +436,8 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
template_parser::expect_no_arguments(function)?;
|
||||
let repo = language.repo;
|
||||
let workspace_id = language.workspace_id.clone();
|
||||
let out_property = TemplateFunction::new(self_property, move |commit| {
|
||||
Ok(Some(commit.id()) == repo.view().get_wc_commit_id(&workspace_id))
|
||||
let out_property = self_property.map(move |commit| {
|
||||
Some(commit.id()) == repo.view().get_wc_commit_id(&workspace_id)
|
||||
});
|
||||
Ok(L::wrap_boolean(out_property))
|
||||
},
|
||||
|
@ -457,13 +447,13 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
|language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let index = language.keyword_cache.branches_index(language.repo).clone();
|
||||
let out_property = TemplateFunction::new(self_property, move |commit| {
|
||||
Ok(index
|
||||
let out_property = self_property.map(move |commit| {
|
||||
index
|
||||
.get(commit.id())
|
||||
.iter()
|
||||
.filter(|ref_name| ref_name.is_local() || !ref_name.synced)
|
||||
.cloned()
|
||||
.collect())
|
||||
.collect()
|
||||
});
|
||||
Ok(L::wrap_ref_name_list(out_property))
|
||||
},
|
||||
|
@ -473,13 +463,13 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
|language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let index = language.keyword_cache.branches_index(language.repo).clone();
|
||||
let out_property = TemplateFunction::new(self_property, move |commit| {
|
||||
Ok(index
|
||||
let out_property = self_property.map(move |commit| {
|
||||
index
|
||||
.get(commit.id())
|
||||
.iter()
|
||||
.filter(|ref_name| ref_name.is_local())
|
||||
.cloned()
|
||||
.collect())
|
||||
.collect()
|
||||
});
|
||||
Ok(L::wrap_ref_name_list(out_property))
|
||||
},
|
||||
|
@ -489,13 +479,13 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
|language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let index = language.keyword_cache.branches_index(language.repo).clone();
|
||||
let out_property = TemplateFunction::new(self_property, move |commit| {
|
||||
Ok(index
|
||||
let out_property = self_property.map(move |commit| {
|
||||
index
|
||||
.get(commit.id())
|
||||
.iter()
|
||||
.filter(|ref_name| ref_name.is_remote())
|
||||
.cloned()
|
||||
.collect())
|
||||
.collect()
|
||||
});
|
||||
Ok(L::wrap_ref_name_list(out_property))
|
||||
},
|
||||
|
@ -503,9 +493,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
map.insert("tags", |language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let index = language.keyword_cache.tags_index(language.repo).clone();
|
||||
let out_property = TemplateFunction::new(self_property, move |commit| {
|
||||
Ok(index.get(commit.id()).to_vec())
|
||||
});
|
||||
let out_property = self_property.map(move |commit| index.get(commit.id()).to_vec());
|
||||
Ok(L::wrap_ref_name_list(out_property))
|
||||
});
|
||||
map.insert(
|
||||
|
@ -513,9 +501,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
|language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let index = language.keyword_cache.git_refs_index(language.repo).clone();
|
||||
let out_property = TemplateFunction::new(self_property, move |commit| {
|
||||
Ok(index.get(commit.id()).to_vec())
|
||||
});
|
||||
let out_property = self_property.map(move |commit| index.get(commit.id()).to_vec());
|
||||
Ok(L::wrap_ref_name_list(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -524,8 +510,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
|language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let repo = language.repo;
|
||||
let out_property =
|
||||
TemplateFunction::new(self_property, |commit| Ok(extract_git_head(repo, &commit)));
|
||||
let out_property = self_property.map(|commit| extract_git_head(repo, &commit));
|
||||
Ok(L::wrap_ref_name_list(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -534,10 +519,10 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
|language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let repo = language.repo;
|
||||
let out_property = TemplateFunction::new(self_property, |commit| {
|
||||
let out_property = self_property.map(|commit| {
|
||||
// The given commit could be hidden in e.g. obslog.
|
||||
let maybe_entries = repo.resolve_change_id(commit.change_id());
|
||||
Ok(maybe_entries.map_or(0, |entries| entries.len()) > 1)
|
||||
maybe_entries.map_or(0, |entries| entries.len()) > 1
|
||||
});
|
||||
Ok(L::wrap_boolean(out_property))
|
||||
},
|
||||
|
@ -545,9 +530,9 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
map.insert("hidden", |language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let repo = language.repo;
|
||||
let out_property = TemplateFunction::new(self_property, |commit| {
|
||||
let out_property = self_property.map(|commit| {
|
||||
let maybe_entries = repo.resolve_change_id(commit.change_id());
|
||||
Ok(maybe_entries.map_or(true, |entries| !entries.contains(commit.id())))
|
||||
maybe_entries.map_or(true, |entries| !entries.contains(commit.id()))
|
||||
});
|
||||
Ok(L::wrap_boolean(out_property))
|
||||
});
|
||||
|
@ -557,8 +542,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
template_parser::expect_no_arguments(function)?;
|
||||
let revset = evaluate_immutable_revset(language, function.name_span)?;
|
||||
let is_immutable = revset.containing_fn();
|
||||
let out_property =
|
||||
TemplateFunction::new(self_property, move |commit| Ok(is_immutable(commit.id())));
|
||||
let out_property = self_property.map(move |commit| is_immutable(commit.id()));
|
||||
Ok(L::wrap_boolean(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -566,15 +550,14 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
"conflict",
|
||||
|_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property =
|
||||
TemplateFunction::new(self_property, |commit| Ok(commit.has_conflict()?));
|
||||
let out_property = self_property.and_then(|commit| Ok(commit.has_conflict()?));
|
||||
Ok(L::wrap_boolean(out_property))
|
||||
},
|
||||
);
|
||||
map.insert("empty", |language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let repo = language.repo;
|
||||
let out_property = TemplateFunction::new(self_property, |commit| {
|
||||
let out_property = self_property.and_then(|commit| {
|
||||
if let [parent] = &commit.parents()[..] {
|
||||
return Ok(parent.tree_id() == commit.tree_id());
|
||||
}
|
||||
|
@ -586,9 +569,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
|||
map.insert("root", |language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let repo = language.repo;
|
||||
let out_property = TemplateFunction::new(self_property, |commit| {
|
||||
Ok(commit.id() == repo.store().root_commit_id())
|
||||
});
|
||||
let out_property = self_property.map(|commit| commit.id() == repo.store().root_commit_id());
|
||||
Ok(L::wrap_boolean(out_property))
|
||||
});
|
||||
map
|
||||
|
@ -682,16 +663,14 @@ fn builtin_ref_name_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Re
|
|||
let mut map = CommitTemplateBuildMethodFnMap::<RefName>::new();
|
||||
map.insert("name", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |ref_name| Ok(ref_name.name));
|
||||
let out_property = self_property.map(|ref_name| ref_name.name);
|
||||
Ok(L::wrap_string(out_property))
|
||||
});
|
||||
map.insert(
|
||||
"remote",
|
||||
|_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |ref_name| {
|
||||
Ok(ref_name.remote.unwrap_or_default())
|
||||
});
|
||||
let out_property = self_property.map(|ref_name| ref_name.remote.unwrap_or_default());
|
||||
Ok(L::wrap_string(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -842,9 +821,8 @@ fn builtin_commit_or_change_id_methods<'repo>(
|
|||
let len_property = len_node
|
||||
.map(|node| template_builder::expect_usize_expression(language, build_ctx, node))
|
||||
.transpose()?;
|
||||
let out_property = TemplateFunction::new((self_property, len_property), |(id, len)| {
|
||||
Ok(id.short(len.unwrap_or(12)))
|
||||
});
|
||||
let out_property =
|
||||
(self_property, len_property).map(|(id, len)| id.short(len.unwrap_or(12)));
|
||||
Ok(L::wrap_string(out_property))
|
||||
});
|
||||
map.insert(
|
||||
|
@ -855,9 +833,8 @@ fn builtin_commit_or_change_id_methods<'repo>(
|
|||
let len_property = len_node
|
||||
.map(|node| template_builder::expect_usize_expression(language, build_ctx, node))
|
||||
.transpose()?;
|
||||
let out_property = TemplateFunction::new((self_property, len_property), |(id, len)| {
|
||||
Ok(id.shortest(language.repo, id_prefix_context, len.unwrap_or(0)))
|
||||
});
|
||||
let out_property = (self_property, len_property)
|
||||
.map(|(id, len)| id.shortest(language.repo, id_prefix_context, len.unwrap_or(0)));
|
||||
Ok(L::wrap_shortest_id_prefix(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -902,23 +879,23 @@ fn builtin_shortest_id_prefix_methods<'repo>(
|
|||
"prefix",
|
||||
|_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |id| Ok(id.prefix));
|
||||
let out_property = self_property.map(|id| id.prefix);
|
||||
Ok(L::wrap_string(out_property))
|
||||
},
|
||||
);
|
||||
map.insert("rest", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |id| Ok(id.rest));
|
||||
let out_property = self_property.map(|id| id.rest);
|
||||
Ok(L::wrap_string(out_property))
|
||||
});
|
||||
map.insert("upper", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |id| Ok(id.to_upper()));
|
||||
let out_property = self_property.map(|id| id.to_upper());
|
||||
Ok(L::wrap_shortest_id_prefix(out_property))
|
||||
});
|
||||
map.insert("lower", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |id| Ok(id.to_lower()));
|
||||
let out_property = self_property.map(|id| id.to_lower());
|
||||
Ok(L::wrap_shortest_id_prefix(out_property))
|
||||
});
|
||||
map
|
||||
|
|
|
@ -59,7 +59,7 @@ impl<'a, C> GenericTemplateLanguage<'a, C> {
|
|||
///
|
||||
/// ```ignore
|
||||
/// language.add_keyword("name", |self_property| {
|
||||
/// let out_property = TemplateFunction::new(self_property, |v| Ok(v.to_string()));
|
||||
/// let out_property = self_property.map(|v| v.to_string());
|
||||
/// Ok(GenericTemplateLanguage::wrap_string(out_property))
|
||||
/// });
|
||||
/// ```
|
||||
|
|
|
@ -29,7 +29,7 @@ use crate::template_builder::{
|
|||
};
|
||||
use crate::template_parser::{self, FunctionCallNode, TemplateParseResult};
|
||||
use crate::templater::{
|
||||
IntoTemplate, PlainTextFormattedProperty, Template, TemplateFunction, TemplateProperty,
|
||||
IntoTemplate, PlainTextFormattedProperty, Template, TemplateProperty, TemplatePropertyExt as _,
|
||||
TimestampRange,
|
||||
};
|
||||
|
||||
|
@ -221,9 +221,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap<Operation> {
|
|||
|language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let current_op_id = language.current_op_id.clone();
|
||||
let out_property = TemplateFunction::new(self_property, move |op| {
|
||||
Ok(Some(op.id()) == current_op_id.as_ref())
|
||||
});
|
||||
let out_property = self_property.map(move |op| Some(op.id()) == current_op_id.as_ref());
|
||||
Ok(L::wrap_boolean(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -231,56 +229,47 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap<Operation> {
|
|||
"description",
|
||||
|_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property =
|
||||
TemplateFunction::new(self_property, |op| Ok(op.metadata().description.clone()));
|
||||
let out_property = self_property.map(|op| op.metadata().description.clone());
|
||||
Ok(L::wrap_string(out_property))
|
||||
},
|
||||
);
|
||||
map.insert("id", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |op| Ok(op.id().clone()));
|
||||
let out_property = self_property.map(|op| op.id().clone());
|
||||
Ok(L::wrap_operation_id(out_property))
|
||||
});
|
||||
map.insert("tags", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |op| {
|
||||
let out_property = self_property.map(|op| {
|
||||
// TODO: introduce map type
|
||||
Ok(op
|
||||
.metadata()
|
||||
op.metadata()
|
||||
.tags
|
||||
.iter()
|
||||
.map(|(key, value)| format!("{key}: {value}"))
|
||||
.join("\n"))
|
||||
.join("\n")
|
||||
});
|
||||
Ok(L::wrap_string(out_property))
|
||||
});
|
||||
map.insert("time", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |op| {
|
||||
Ok(TimestampRange {
|
||||
start: op.metadata().start_time.clone(),
|
||||
end: op.metadata().end_time.clone(),
|
||||
})
|
||||
let out_property = self_property.map(|op| TimestampRange {
|
||||
start: op.metadata().start_time.clone(),
|
||||
end: op.metadata().end_time.clone(),
|
||||
});
|
||||
Ok(L::wrap_timestamp_range(out_property))
|
||||
});
|
||||
map.insert("user", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |op| {
|
||||
let out_property = self_property.map(|op| {
|
||||
// TODO: introduce dedicated type and provide accessors?
|
||||
Ok(format!(
|
||||
"{}@{}",
|
||||
op.metadata().username,
|
||||
op.metadata().hostname
|
||||
))
|
||||
format!("{}@{}", op.metadata().username, op.metadata().hostname)
|
||||
});
|
||||
Ok(L::wrap_string(out_property))
|
||||
});
|
||||
map.insert("root", |language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let root_op_id = language.root_op_id.clone();
|
||||
let out_property =
|
||||
TemplateFunction::new(self_property, move |op| Ok(op.id() == &root_op_id));
|
||||
let out_property = self_property.map(move |op| op.id() == &root_op_id);
|
||||
Ok(L::wrap_boolean(out_property))
|
||||
});
|
||||
map
|
||||
|
@ -302,10 +291,10 @@ fn builtin_operation_id_methods() -> OperationTemplateBuildMethodFnMap<Operation
|
|||
let len_property = len_node
|
||||
.map(|node| template_builder::expect_usize_expression(language, build_ctx, node))
|
||||
.transpose()?;
|
||||
let out_property = TemplateFunction::new((self_property, len_property), |(id, len)| {
|
||||
let out_property = (self_property, len_property).map(|(id, len)| {
|
||||
let mut hex = id.hex();
|
||||
hex.truncate(len.unwrap_or(12));
|
||||
Ok(hex)
|
||||
hex
|
||||
});
|
||||
Ok(L::wrap_string(out_property))
|
||||
});
|
||||
|
|
|
@ -24,8 +24,8 @@ use crate::template_parser::{
|
|||
use crate::templater::{
|
||||
ConcatTemplate, ConditionalTemplate, IntoTemplate, LabelTemplate, ListPropertyTemplate,
|
||||
ListTemplate, Literal, PlaceholderTemplate, PlainTextFormattedProperty, PropertyPlaceholder,
|
||||
ReformatTemplate, SeparateTemplate, Template, TemplateFunction, TemplateProperty,
|
||||
TemplatePropertyError, TimestampRange,
|
||||
ReformatTemplate, SeparateTemplate, Template, TemplateProperty, TemplatePropertyError,
|
||||
TemplatePropertyExt as _, TimestampRange,
|
||||
};
|
||||
use crate::{text_util, time_util};
|
||||
|
||||
|
@ -147,14 +147,10 @@ impl<'a> IntoTemplateProperty<'a> for CoreTemplatePropertyKind<'a> {
|
|||
fn try_into_boolean(self) -> Option<Box<dyn TemplateProperty<Output = bool> + 'a>> {
|
||||
match self {
|
||||
CoreTemplatePropertyKind::String(property) => {
|
||||
Some(Box::new(TemplateFunction::new(property, |s| {
|
||||
Ok(!s.is_empty())
|
||||
})))
|
||||
Some(Box::new(property.map(|s| !s.is_empty())))
|
||||
}
|
||||
CoreTemplatePropertyKind::StringList(property) => {
|
||||
Some(Box::new(TemplateFunction::new(property, |l| {
|
||||
Ok(!l.is_empty())
|
||||
})))
|
||||
Some(Box::new(property.map(|l| !l.is_empty())))
|
||||
}
|
||||
CoreTemplatePropertyKind::Boolean(property) => Some(property),
|
||||
CoreTemplatePropertyKind::Integer(_) => None,
|
||||
|
@ -473,11 +469,11 @@ fn build_unary_operation<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
match op {
|
||||
UnaryOp::LogicalNot => {
|
||||
let arg = expect_boolean_expression(language, build_ctx, arg_node)?;
|
||||
Ok(L::wrap_boolean(TemplateFunction::new(arg, |v| Ok(!v))))
|
||||
Ok(L::wrap_boolean(arg.map(|v| !v)))
|
||||
}
|
||||
UnaryOp::Negate => {
|
||||
let arg = expect_integer_expression(language, build_ctx, arg_node)?;
|
||||
Ok(L::wrap_integer(TemplateFunction::new(arg, |v| {
|
||||
Ok(L::wrap_integer(arg.and_then(|v| {
|
||||
v.checked_neg()
|
||||
.ok_or_else(|| TemplatePropertyError("Attempt to negate with overflow".into()))
|
||||
})))
|
||||
|
@ -497,19 +493,13 @@ fn build_binary_operation<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
// No short-circuiting supported
|
||||
let lhs = expect_boolean_expression(language, build_ctx, lhs_node)?;
|
||||
let rhs = expect_boolean_expression(language, build_ctx, rhs_node)?;
|
||||
Ok(L::wrap_boolean(TemplateFunction::new(
|
||||
(lhs, rhs),
|
||||
|(l, r)| Ok(l | r),
|
||||
)))
|
||||
Ok(L::wrap_boolean((lhs, rhs).map(|(l, r)| l | r)))
|
||||
}
|
||||
BinaryOp::LogicalAnd => {
|
||||
// No short-circuiting supported
|
||||
let lhs = expect_boolean_expression(language, build_ctx, lhs_node)?;
|
||||
let rhs = expect_boolean_expression(language, build_ctx, rhs_node)?;
|
||||
Ok(L::wrap_boolean(TemplateFunction::new(
|
||||
(lhs, rhs),
|
||||
|(l, r)| Ok(l & r),
|
||||
)))
|
||||
Ok(L::wrap_boolean((lhs, rhs).map(|(l, r)| l & r)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -521,7 +511,7 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
let mut map = TemplateBuildMethodFnMap::<L, String>::new();
|
||||
map.insert("len", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |s| Ok(s.len().try_into()?));
|
||||
let out_property = self_property.and_then(|s| Ok(s.len().try_into()?));
|
||||
Ok(L::wrap_integer(out_property))
|
||||
});
|
||||
map.insert(
|
||||
|
@ -530,10 +520,8 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
let [needle_node] = template_parser::expect_exact_arguments(function)?;
|
||||
// TODO: or .try_into_string() to disable implicit type cast?
|
||||
let needle_property = expect_plain_text_expression(language, build_ctx, needle_node)?;
|
||||
let out_property =
|
||||
TemplateFunction::new((self_property, needle_property), |(haystack, needle)| {
|
||||
Ok(haystack.contains(&needle))
|
||||
});
|
||||
let out_property = (self_property, needle_property)
|
||||
.map(|(haystack, needle)| haystack.contains(&needle));
|
||||
Ok(L::wrap_boolean(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -542,10 +530,8 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
|language, build_ctx, self_property, function| {
|
||||
let [needle_node] = template_parser::expect_exact_arguments(function)?;
|
||||
let needle_property = expect_plain_text_expression(language, build_ctx, needle_node)?;
|
||||
let out_property =
|
||||
TemplateFunction::new((self_property, needle_property), |(haystack, needle)| {
|
||||
Ok(haystack.starts_with(&needle))
|
||||
});
|
||||
let out_property = (self_property, needle_property)
|
||||
.map(|(haystack, needle)| haystack.starts_with(&needle));
|
||||
Ok(L::wrap_boolean(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -554,10 +540,8 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
|language, build_ctx, self_property, function| {
|
||||
let [needle_node] = template_parser::expect_exact_arguments(function)?;
|
||||
let needle_property = expect_plain_text_expression(language, build_ctx, needle_node)?;
|
||||
let out_property =
|
||||
TemplateFunction::new((self_property, needle_property), |(haystack, needle)| {
|
||||
Ok(haystack.ends_with(&needle))
|
||||
});
|
||||
let out_property = (self_property, needle_property)
|
||||
.map(|(haystack, needle)| haystack.ends_with(&needle));
|
||||
Ok(L::wrap_boolean(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -566,13 +550,12 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
|language, build_ctx, self_property, function| {
|
||||
let [needle_node] = template_parser::expect_exact_arguments(function)?;
|
||||
let needle_property = expect_plain_text_expression(language, build_ctx, needle_node)?;
|
||||
let out_property =
|
||||
TemplateFunction::new((self_property, needle_property), |(haystack, needle)| {
|
||||
Ok(haystack
|
||||
.strip_prefix(&needle)
|
||||
.map(ToOwned::to_owned)
|
||||
.unwrap_or(haystack))
|
||||
});
|
||||
let out_property = (self_property, needle_property).map(|(haystack, needle)| {
|
||||
haystack
|
||||
.strip_prefix(&needle)
|
||||
.map(ToOwned::to_owned)
|
||||
.unwrap_or(haystack)
|
||||
});
|
||||
Ok(L::wrap_string(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -581,13 +564,12 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
|language, build_ctx, self_property, function| {
|
||||
let [needle_node] = template_parser::expect_exact_arguments(function)?;
|
||||
let needle_property = expect_plain_text_expression(language, build_ctx, needle_node)?;
|
||||
let out_property =
|
||||
TemplateFunction::new((self_property, needle_property), |(haystack, needle)| {
|
||||
Ok(haystack
|
||||
.strip_suffix(&needle)
|
||||
.map(ToOwned::to_owned)
|
||||
.unwrap_or(haystack))
|
||||
});
|
||||
let out_property = (self_property, needle_property).map(|(haystack, needle)| {
|
||||
haystack
|
||||
.strip_suffix(&needle)
|
||||
.map(ToOwned::to_owned)
|
||||
.unwrap_or(haystack)
|
||||
});
|
||||
Ok(L::wrap_string(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -595,41 +577,36 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
let [start_idx, end_idx] = template_parser::expect_exact_arguments(function)?;
|
||||
let start_idx_property = expect_isize_expression(language, build_ctx, start_idx)?;
|
||||
let end_idx_property = expect_isize_expression(language, build_ctx, end_idx)?;
|
||||
let out_property = TemplateFunction::new(
|
||||
(self_property, start_idx_property, end_idx_property),
|
||||
|(s, start_idx, end_idx)| {
|
||||
let out_property =
|
||||
(self_property, start_idx_property, end_idx_property).map(|(s, start_idx, end_idx)| {
|
||||
let start_idx = string_index_to_char_boundary(&s, start_idx);
|
||||
let end_idx = string_index_to_char_boundary(&s, end_idx);
|
||||
Ok(s.get(start_idx..end_idx).unwrap_or_default().to_owned())
|
||||
},
|
||||
);
|
||||
s.get(start_idx..end_idx).unwrap_or_default().to_owned()
|
||||
});
|
||||
Ok(L::wrap_string(out_property))
|
||||
});
|
||||
map.insert(
|
||||
"first_line",
|
||||
|_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |s| {
|
||||
Ok(s.lines().next().unwrap_or_default().to_string())
|
||||
});
|
||||
let out_property =
|
||||
self_property.map(|s| s.lines().next().unwrap_or_default().to_string());
|
||||
Ok(L::wrap_string(out_property))
|
||||
},
|
||||
);
|
||||
map.insert("lines", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |s| {
|
||||
Ok(s.lines().map(|l| l.to_owned()).collect())
|
||||
});
|
||||
let out_property = self_property.map(|s| s.lines().map(|l| l.to_owned()).collect());
|
||||
Ok(L::wrap_string_list(out_property))
|
||||
});
|
||||
map.insert("upper", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |s| Ok(s.to_uppercase()));
|
||||
let out_property = self_property.map(|s| s.to_uppercase());
|
||||
Ok(L::wrap_string(out_property))
|
||||
});
|
||||
map.insert("lower", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |s| Ok(s.to_lowercase()));
|
||||
let out_property = self_property.map(|s| s.to_lowercase());
|
||||
Ok(L::wrap_string(out_property))
|
||||
});
|
||||
map
|
||||
|
@ -658,21 +635,21 @@ fn builtin_signature_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
let mut map = TemplateBuildMethodFnMap::<L, Signature>::new();
|
||||
map.insert("name", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |signature| Ok(signature.name));
|
||||
let out_property = self_property.map(|signature| signature.name);
|
||||
Ok(L::wrap_string(out_property))
|
||||
});
|
||||
map.insert("email", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |signature| Ok(signature.email));
|
||||
let out_property = self_property.map(|signature| signature.email);
|
||||
Ok(L::wrap_string(out_property))
|
||||
});
|
||||
map.insert(
|
||||
"username",
|
||||
|_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |signature| {
|
||||
let out_property = self_property.map(|signature| {
|
||||
let (username, _) = text_util::split_email(&signature.email);
|
||||
Ok(username.to_owned())
|
||||
username.to_owned()
|
||||
});
|
||||
Ok(L::wrap_string(out_property))
|
||||
},
|
||||
|
@ -681,8 +658,7 @@ fn builtin_signature_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
"timestamp",
|
||||
|_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property =
|
||||
TemplateFunction::new(self_property, |signature| Ok(signature.timestamp));
|
||||
let out_property = self_property.map(|signature| signature.timestamp);
|
||||
Ok(L::wrap_timestamp(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -698,9 +674,8 @@ fn builtin_timestamp_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
template_parser::expect_no_arguments(function)?;
|
||||
let now = Timestamp::now();
|
||||
let format = timeago::Formatter::new();
|
||||
let out_property = TemplateFunction::new(self_property, move |timestamp| {
|
||||
Ok(time_util::format_duration(×tamp, &now, &format)?)
|
||||
});
|
||||
let out_property = self_property
|
||||
.and_then(move |timestamp| Ok(time_util::format_duration(×tamp, &now, &format)?));
|
||||
Ok(L::wrap_string(out_property))
|
||||
});
|
||||
map.insert(
|
||||
|
@ -715,7 +690,7 @@ fn builtin_timestamp_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
})
|
||||
})?
|
||||
.into_owned();
|
||||
let out_property = TemplateFunction::new(self_property, move |timestamp| {
|
||||
let out_property = self_property.and_then(move |timestamp| {
|
||||
Ok(time_util::format_absolute_timestamp_with(
|
||||
×tamp, &format,
|
||||
)?)
|
||||
|
@ -725,9 +700,9 @@ fn builtin_timestamp_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
);
|
||||
map.insert("utc", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |mut timestamp| {
|
||||
let out_property = self_property.map(|mut timestamp| {
|
||||
timestamp.tz_offset = 0;
|
||||
Ok(timestamp)
|
||||
timestamp
|
||||
});
|
||||
Ok(L::wrap_timestamp(out_property))
|
||||
});
|
||||
|
@ -737,9 +712,9 @@ fn builtin_timestamp_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
.ok()
|
||||
.and_then(|tz_string| tz_string.parse::<i32>().ok())
|
||||
.unwrap_or_else(|| chrono::Local::now().offset().local_minus_utc() / 60);
|
||||
let out_property = TemplateFunction::new(self_property, move |mut timestamp| {
|
||||
let out_property = self_property.map(move |mut timestamp| {
|
||||
timestamp.tz_offset = tz_offset;
|
||||
Ok(timestamp)
|
||||
timestamp
|
||||
});
|
||||
Ok(L::wrap_timestamp(out_property))
|
||||
});
|
||||
|
@ -753,20 +728,19 @@ fn builtin_timestamp_range_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
let mut map = TemplateBuildMethodFnMap::<L, TimestampRange>::new();
|
||||
map.insert("start", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |time_range| Ok(time_range.start));
|
||||
let out_property = self_property.map(|time_range| time_range.start);
|
||||
Ok(L::wrap_timestamp(out_property))
|
||||
});
|
||||
map.insert("end", |_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property = TemplateFunction::new(self_property, |time_range| Ok(time_range.end));
|
||||
let out_property = self_property.map(|time_range| time_range.end);
|
||||
Ok(L::wrap_timestamp(out_property))
|
||||
});
|
||||
map.insert(
|
||||
"duration",
|
||||
|_language, _build_ctx, self_property, function| {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property =
|
||||
TemplateFunction::new(self_property, |time_range| Ok(time_range.duration()?));
|
||||
let out_property = self_property.and_then(|time_range| Ok(time_range.duration()?));
|
||||
Ok(L::wrap_string(out_property))
|
||||
},
|
||||
);
|
||||
|
@ -807,8 +781,7 @@ where
|
|||
let property = match function.name {
|
||||
"len" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property =
|
||||
TemplateFunction::new(self_property, |items| Ok(items.len().try_into()?));
|
||||
let out_property = self_property.and_then(|items| Ok(items.len().try_into()?));
|
||||
L::wrap_integer(out_property)
|
||||
}
|
||||
"join" => {
|
||||
|
@ -840,8 +813,7 @@ where
|
|||
let property = match function.name {
|
||||
"len" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let out_property =
|
||||
TemplateFunction::new(self_property, |items| Ok(items.len().try_into()?));
|
||||
let out_property = self_property.and_then(|items| Ok(items.len().try_into()?));
|
||||
L::wrap_integer(out_property)
|
||||
}
|
||||
// No "join"
|
||||
|
@ -930,9 +902,8 @@ fn builtin_functions<'a, L: TemplateLanguage<'a> + ?Sized>() -> TemplateBuildFun
|
|||
let [label_node, content_node] = template_parser::expect_exact_arguments(function)?;
|
||||
let label_property = expect_plain_text_expression(language, build_ctx, label_node)?;
|
||||
let content = expect_template_expression(language, build_ctx, content_node)?;
|
||||
let labels = TemplateFunction::new(label_property, |s| {
|
||||
Ok(s.split_whitespace().map(ToString::to_string).collect())
|
||||
});
|
||||
let labels =
|
||||
label_property.map(|s| s.split_whitespace().map(ToString::to_string).collect());
|
||||
Ok(L::wrap_template(Box::new(LabelTemplate::new(
|
||||
content, labels,
|
||||
))))
|
||||
|
@ -1123,7 +1094,7 @@ pub fn expect_isize_expression<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
node: &ExpressionNode,
|
||||
) -> TemplateParseResult<Box<dyn TemplateProperty<Output = isize> + 'a>> {
|
||||
let i64_property = expect_integer_expression(language, build_ctx, node)?;
|
||||
let isize_property = TemplateFunction::new(i64_property, |v| Ok(isize::try_from(v)?));
|
||||
let isize_property = i64_property.and_then(|v| Ok(isize::try_from(v)?));
|
||||
Ok(Box::new(isize_property))
|
||||
}
|
||||
|
||||
|
@ -1134,7 +1105,7 @@ pub fn expect_usize_expression<'a, L: TemplateLanguage<'a> + ?Sized>(
|
|||
node: &ExpressionNode,
|
||||
) -> TemplateParseResult<Box<dyn TemplateProperty<Output = usize> + 'a>> {
|
||||
let i64_property = expect_integer_expression(language, build_ctx, node)?;
|
||||
let usize_property = TemplateFunction::new(i64_property, |v| Ok(usize::try_from(v)?));
|
||||
let usize_property = i64_property.and_then(|v| Ok(usize::try_from(v)?));
|
||||
Ok(Box::new(usize_property))
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue