mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-29 07:43:34 +00:00
templater: merge build_*_keyword_opt() functions into method builders
template_parser::expect_no_arguments(function) is copied to each method body. We might want to add some helper macros later.
This commit is contained in:
parent
e588a9babc
commit
f0ce448609
2 changed files with 127 additions and 99 deletions
|
@ -243,20 +243,6 @@ fn build_commit_method<'repo>(
|
|||
self_property: impl TemplateProperty<Commit, Output = Commit> + 'repo,
|
||||
function: &FunctionCallNode,
|
||||
) -> TemplateParseResult<CommitTemplatePropertyKind<'repo>> {
|
||||
if let Some(property) = build_commit_keyword_opt(language, self_property, function.name) {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
Ok(property)
|
||||
} else {
|
||||
Err(TemplateParseError::no_such_method("Commit", function))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: merge into build_commit_method()
|
||||
fn build_commit_keyword_opt<'repo>(
|
||||
language: &CommitTemplateLanguage<'repo, '_>,
|
||||
property: impl TemplateProperty<Commit, Output = Commit> + 'repo,
|
||||
name: &str,
|
||||
) -> Option<CommitTemplatePropertyKind<'repo>> {
|
||||
fn wrap_fn<'repo, O>(
|
||||
property: impl TemplateProperty<Commit, Output = Commit> + 'repo,
|
||||
f: impl Fn(&Commit) -> O + 'repo,
|
||||
|
@ -273,33 +259,52 @@ fn build_commit_keyword_opt<'repo>(
|
|||
|
||||
let repo = language.repo;
|
||||
let cache = &language.keyword_cache;
|
||||
let property = match name {
|
||||
"description" => language.wrap_string(wrap_fn(property, |commit| {
|
||||
text_util::complete_newline(commit.description())
|
||||
})),
|
||||
"change_id" => language.wrap_commit_or_change_id(wrap_fn(property, |commit| {
|
||||
CommitOrChangeId::Change(commit.change_id().to_owned())
|
||||
})),
|
||||
"commit_id" => language.wrap_commit_or_change_id(wrap_fn(property, |commit| {
|
||||
CommitOrChangeId::Commit(commit.id().to_owned())
|
||||
})),
|
||||
"parents" => language.wrap_commit_list(wrap_fn(property, |commit| commit.parents())),
|
||||
"author" => language.wrap_signature(wrap_fn(property, |commit| commit.author().clone())),
|
||||
let property = match function.name {
|
||||
"description" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_string(wrap_fn(self_property, |commit| {
|
||||
text_util::complete_newline(commit.description())
|
||||
}))
|
||||
}
|
||||
"change_id" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_commit_or_change_id(wrap_fn(self_property, |commit| {
|
||||
CommitOrChangeId::Change(commit.change_id().to_owned())
|
||||
}))
|
||||
}
|
||||
"commit_id" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_commit_or_change_id(wrap_fn(self_property, |commit| {
|
||||
CommitOrChangeId::Commit(commit.id().to_owned())
|
||||
}))
|
||||
}
|
||||
"parents" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_commit_list(wrap_fn(self_property, |commit| commit.parents()))
|
||||
}
|
||||
"author" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_signature(wrap_fn(self_property, |commit| commit.author().clone()))
|
||||
}
|
||||
"committer" => {
|
||||
language.wrap_signature(wrap_fn(property, |commit| commit.committer().clone()))
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_signature(wrap_fn(self_property, |commit| commit.committer().clone()))
|
||||
}
|
||||
"working_copies" => {
|
||||
language.wrap_string(wrap_repo_fn(repo, property, extract_working_copies))
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_string(wrap_repo_fn(repo, self_property, extract_working_copies))
|
||||
}
|
||||
"current_working_copy" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let workspace_id = language.workspace_id.clone();
|
||||
language.wrap_boolean(wrap_fn(property, move |commit| {
|
||||
language.wrap_boolean(wrap_fn(self_property, move |commit| {
|
||||
Some(commit.id()) == repo.view().get_wc_commit_id(&workspace_id)
|
||||
}))
|
||||
}
|
||||
"branches" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let index = cache.branches_index(repo).clone();
|
||||
language.wrap_ref_name_list(wrap_fn(property, move |commit| {
|
||||
language.wrap_ref_name_list(wrap_fn(self_property, move |commit| {
|
||||
index
|
||||
.get(commit.id())
|
||||
.iter()
|
||||
|
@ -309,8 +314,9 @@ fn build_commit_keyword_opt<'repo>(
|
|||
}))
|
||||
}
|
||||
"local_branches" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let index = cache.branches_index(repo).clone();
|
||||
language.wrap_ref_name_list(wrap_fn(property, move |commit| {
|
||||
language.wrap_ref_name_list(wrap_fn(self_property, move |commit| {
|
||||
index
|
||||
.get(commit.id())
|
||||
.iter()
|
||||
|
@ -320,8 +326,9 @@ fn build_commit_keyword_opt<'repo>(
|
|||
}))
|
||||
}
|
||||
"remote_branches" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let index = cache.branches_index(repo).clone();
|
||||
language.wrap_ref_name_list(wrap_fn(property, move |commit| {
|
||||
language.wrap_ref_name_list(wrap_fn(self_property, move |commit| {
|
||||
index
|
||||
.get(commit.id())
|
||||
.iter()
|
||||
|
@ -331,43 +338,61 @@ fn build_commit_keyword_opt<'repo>(
|
|||
}))
|
||||
}
|
||||
"tags" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let index = cache.tags_index(repo).clone();
|
||||
language.wrap_ref_name_list(wrap_fn(property, move |commit| {
|
||||
language.wrap_ref_name_list(wrap_fn(self_property, move |commit| {
|
||||
index.get(commit.id()).to_vec()
|
||||
}))
|
||||
}
|
||||
"git_refs" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let index = cache.git_refs_index(repo).clone();
|
||||
language.wrap_ref_name_list(wrap_fn(property, move |commit| {
|
||||
language.wrap_ref_name_list(wrap_fn(self_property, move |commit| {
|
||||
index.get(commit.id()).to_vec()
|
||||
}))
|
||||
}
|
||||
"git_head" => language.wrap_ref_name_list(wrap_repo_fn(repo, property, extract_git_head)),
|
||||
"divergent" => language.wrap_boolean(wrap_fn(property, |commit| {
|
||||
// The given commit could be hidden in e.g. obslog.
|
||||
let maybe_entries = repo.resolve_change_id(commit.change_id());
|
||||
maybe_entries.map_or(0, |entries| entries.len()) > 1
|
||||
})),
|
||||
"hidden" => language.wrap_boolean(wrap_fn(property, |commit| {
|
||||
let maybe_entries = repo.resolve_change_id(commit.change_id());
|
||||
maybe_entries.map_or(true, |entries| !entries.contains(commit.id()))
|
||||
})),
|
||||
"conflict" => {
|
||||
language.wrap_boolean(wrap_fn(property, |commit| commit.has_conflict().unwrap()))
|
||||
"git_head" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_ref_name_list(wrap_repo_fn(repo, self_property, extract_git_head))
|
||||
}
|
||||
"empty" => language.wrap_boolean(wrap_fn(property, |commit| {
|
||||
if let [parent] = &commit.parents()[..] {
|
||||
return parent.tree_id() == commit.tree_id();
|
||||
}
|
||||
let parent_tree = rewrite::merge_commit_trees(repo, &commit.parents()).unwrap();
|
||||
*commit.tree_id() == parent_tree.id()
|
||||
})),
|
||||
"root" => language.wrap_boolean(wrap_fn(property, move |commit| {
|
||||
commit.id() == repo.store().root_commit_id()
|
||||
})),
|
||||
_ => return None,
|
||||
"divergent" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_boolean(wrap_fn(self_property, |commit| {
|
||||
// The given commit could be hidden in e.g. obslog.
|
||||
let maybe_entries = repo.resolve_change_id(commit.change_id());
|
||||
maybe_entries.map_or(0, |entries| entries.len()) > 1
|
||||
}))
|
||||
}
|
||||
"hidden" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_boolean(wrap_fn(self_property, |commit| {
|
||||
let maybe_entries = repo.resolve_change_id(commit.change_id());
|
||||
maybe_entries.map_or(true, |entries| !entries.contains(commit.id()))
|
||||
}))
|
||||
}
|
||||
"conflict" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_boolean(wrap_fn(self_property, |commit| commit.has_conflict().unwrap()))
|
||||
}
|
||||
"empty" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_boolean(wrap_fn(self_property, |commit| {
|
||||
if let [parent] = &commit.parents()[..] {
|
||||
return parent.tree_id() == commit.tree_id();
|
||||
}
|
||||
let parent_tree = rewrite::merge_commit_trees(repo, &commit.parents()).unwrap();
|
||||
*commit.tree_id() == parent_tree.id()
|
||||
}))
|
||||
}
|
||||
"root" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_boolean(wrap_fn(self_property, move |commit| {
|
||||
commit.id() == repo.store().root_commit_id()
|
||||
}))
|
||||
}
|
||||
_ => return Err(TemplateParseError::no_such_method("Commit", function)),
|
||||
};
|
||||
Some(property)
|
||||
Ok(property)
|
||||
}
|
||||
|
||||
// TODO: return Vec<String>
|
||||
|
|
|
@ -130,20 +130,6 @@ fn build_operation_method(
|
|||
self_property: impl TemplateProperty<Operation, Output = Operation> + 'static,
|
||||
function: &FunctionCallNode,
|
||||
) -> TemplateParseResult<OperationTemplatePropertyKind> {
|
||||
if let Some(property) = build_operation_keyword_opt(language, self_property, function.name) {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
Ok(property)
|
||||
} else {
|
||||
Err(TemplateParseError::no_such_method("Operation", function))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: merge into build_operation_method()
|
||||
fn build_operation_keyword_opt(
|
||||
language: &OperationTemplateLanguage,
|
||||
property: impl TemplateProperty<Operation, Output = Operation> + 'static,
|
||||
name: &str,
|
||||
) -> Option<OperationTemplatePropertyKind> {
|
||||
fn wrap_fn<O>(
|
||||
property: impl TemplateProperty<Operation, Output = Operation>,
|
||||
f: impl Fn(&Operation) -> O,
|
||||
|
@ -157,42 +143,59 @@ fn build_operation_keyword_opt(
|
|||
TemplateFunction::new(property, move |op| f(op.metadata()))
|
||||
}
|
||||
|
||||
let property = match name {
|
||||
let property = match function.name {
|
||||
"current_operation" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let current_op_id = language.current_op_id.cloned();
|
||||
language.wrap_boolean(wrap_fn(property, move |op| {
|
||||
language.wrap_boolean(wrap_fn(self_property, move |op| {
|
||||
Some(op.id()) == current_op_id.as_ref()
|
||||
}))
|
||||
}
|
||||
"description" => language.wrap_string(wrap_metadata_fn(property, |metadata| {
|
||||
metadata.description.clone()
|
||||
})),
|
||||
"id" => language.wrap_operation_id(wrap_fn(property, |op| op.id().clone())),
|
||||
"tags" => language.wrap_string(wrap_metadata_fn(property, |metadata| {
|
||||
// TODO: introduce map type
|
||||
metadata
|
||||
.tags
|
||||
.iter()
|
||||
.map(|(key, value)| format!("{key}: {value}"))
|
||||
.join("\n")
|
||||
})),
|
||||
"time" => {
|
||||
language.wrap_timestamp_range(wrap_metadata_fn(property, |metadata| TimestampRange {
|
||||
start: metadata.start_time.clone(),
|
||||
end: metadata.end_time.clone(),
|
||||
"description" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_string(wrap_metadata_fn(self_property, |metadata| {
|
||||
metadata.description.clone()
|
||||
}))
|
||||
}
|
||||
"user" => language.wrap_string(wrap_metadata_fn(property, |metadata| {
|
||||
// TODO: introduce dedicated type and provide accessors?
|
||||
format!("{}@{}", metadata.username, metadata.hostname)
|
||||
})),
|
||||
"root" => {
|
||||
let root_op_id = language.root_op_id.clone();
|
||||
language.wrap_boolean(wrap_fn(property, move |op| op.id() == &root_op_id))
|
||||
"id" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_operation_id(wrap_fn(self_property, |op| op.id().clone()))
|
||||
}
|
||||
_ => return None,
|
||||
"tags" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_string(wrap_metadata_fn(self_property, |metadata| {
|
||||
// TODO: introduce map type
|
||||
metadata
|
||||
.tags
|
||||
.iter()
|
||||
.map(|(key, value)| format!("{key}: {value}"))
|
||||
.join("\n")
|
||||
}))
|
||||
}
|
||||
"time" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_timestamp_range(wrap_metadata_fn(self_property, |metadata| {
|
||||
TimestampRange {
|
||||
start: metadata.start_time.clone(),
|
||||
end: metadata.end_time.clone(),
|
||||
}
|
||||
}))
|
||||
}
|
||||
"user" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
language.wrap_string(wrap_metadata_fn(self_property, |metadata| {
|
||||
// TODO: introduce dedicated type and provide accessors?
|
||||
format!("{}@{}", metadata.username, metadata.hostname)
|
||||
}))
|
||||
}
|
||||
"root" => {
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
let root_op_id = language.root_op_id.clone();
|
||||
language.wrap_boolean(wrap_fn(self_property, move |op| op.id() == &root_op_id))
|
||||
}
|
||||
_ => return Err(TemplateParseError::no_such_method("Operation", function)),
|
||||
};
|
||||
Some(property)
|
||||
Ok(property)
|
||||
}
|
||||
|
||||
impl Template<()> for OperationId {
|
||||
|
|
Loading…
Reference in a new issue