Skip to content

Commit

Permalink
commit_templater: add an AnyMap for extensions to cache their own info
Browse files Browse the repository at this point in the history
  • Loading branch information
torquestomp committed Mar 6, 2024
1 parent fd3cb90 commit ddea3b4
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 4 deletions.
51 changes: 47 additions & 4 deletions cli/examples/custom-commit-templater/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,22 @@ use jj_cli::commit_templater::{CommitTemplateBuildFnTable, CommitTemplateLanguag
use jj_cli::template_builder::TemplateLanguage;
use jj_cli::template_parser::{self, TemplateParseError};
use jj_cli::templater::{TemplateFunction, TemplatePropertyError};
use jj_lib::backend::CommitId;
use jj_lib::commit::Commit;
use jj_lib::object_id::ObjectId;
use jj_lib::repo::Repo;
use jj_lib::revset::RevsetExpression;

struct HexCounter;

fn num_digits_in_id(commit: Commit) -> Result<i64, TemplatePropertyError> {
fn num_digits_in_id(id: &CommitId) -> i64 {
let mut count = 0;
for ch in commit.id().hex().chars() {
for ch in id.hex().chars() {
if ch.is_ascii_digit() {
count += 1;
}
}
Ok(count)
count
}

fn num_char_in_id(commit: Commit, ch_match: char) -> Result<i64, TemplatePropertyError> {
Expand All @@ -42,14 +45,54 @@ fn num_char_in_id(commit: Commit, ch_match: char) -> Result<i64, TemplatePropert
Ok(count)
}

#[derive(Default)]
struct MostDigitsInId {
count: i64,
}

impl MostDigitsInId {
fn new(repo: &dyn Repo) -> Self {
let count = RevsetExpression::all()
.evaluate_programmatic(repo)
.unwrap()
.iter()
.map(|id| num_digits_in_id(&id))
.max()
.unwrap_or(0);
Self { count }
}

fn count(&self) -> i64 {
self.count
}
}

impl CommitTemplateLanguageExtension for HexCounter {
fn build_fn_table<'repo>(&self) -> CommitTemplateBuildFnTable<'repo> {
let mut table = CommitTemplateBuildFnTable::empty();
table.commit_methods.insert(
"has_most_digits",
|language, _build_context, property, call| {
template_parser::expect_no_arguments(call)?;
let most_digits = language
.cache_extension(|| MostDigitsInId::new(language.repo()))
.count();
Ok(
language.wrap_boolean(TemplateFunction::new(property, move |commit| {
Ok(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(language.wrap_integer(TemplateFunction::new(property, num_digits_in_id)))
Ok(
language.wrap_integer(TemplateFunction::new(property, |commit| {
Ok(num_digits_in_id(commit.id()))
})),
)
},
);
table.commit_methods.insert(
Expand Down
8 changes: 8 additions & 0 deletions cli/src/commit_templater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::any::Any;
use std::cmp::max;
use std::collections::HashMap;
use std::io;
use std::rc::Rc;

use itertools::Itertools as _;
use jj_lib::any_map::AnyMap;
use jj_lib::backend::{ChangeId, CommitId};
use jj_lib::commit::Commit;
use jj_lib::hex_util::to_reverse_hex;
Expand Down Expand Up @@ -50,6 +52,7 @@ pub struct CommitTemplateLanguage<'repo> {
id_prefix_context: &'repo IdPrefixContext,
build_fn_table: CommitTemplateBuildFnTable<'repo>,
keyword_cache: CommitKeywordCache,
cache_extensions: AnyMap,
}

impl<'repo> CommitTemplateLanguage<'repo> {
Expand All @@ -71,6 +74,7 @@ impl<'repo> CommitTemplateLanguage<'repo> {
id_prefix_context,
build_fn_table,
keyword_cache: CommitKeywordCache::default(),
cache_extensions: AnyMap::new(),
}
}
}
Expand Down Expand Up @@ -156,6 +160,10 @@ impl<'repo> CommitTemplateLanguage<'repo> {
&self.keyword_cache
}

pub fn cache_extension<T: Any>(&self, generator: impl FnOnce() -> T) -> &T {
self.cache_extensions.insert(generator)
}

pub fn wrap_commit(
&self,
property: impl TemplateProperty<Commit, Output = Commit> + 'repo,
Expand Down

0 comments on commit ddea3b4

Please sign in to comment.