diff --git a/src/template_parser.rs b/src/template_parser.rs index 99a822a47..1fad14aef 100644 --- a/src/template_parser.rs +++ b/src/template_parser.rs @@ -99,10 +99,7 @@ impl TemplateProperty for RelativeTimestampString { enum Property<'a, I> { String(Box + 'a>), Boolean(Box + 'a>), - CommitOrChangeId( - Box + 'a>, - RepoRef<'a>, - ), + CommitOrChangeId(Box> + 'a>), Signature(Box + 'a>), Timestamp(Box + 'a>), } @@ -121,8 +118,8 @@ impl<'a, I: 'a> Property<'a, I> { match self { Property::String(property) => Property::String(chain(first, property)), Property::Boolean(property) => Property::Boolean(chain(first, property)), - Property::CommitOrChangeId(property, repo) => { - Property::CommitOrChangeId(chain(first, property), repo) + Property::CommitOrChangeId(property) => { + Property::CommitOrChangeId(chain(first, property)) } Property::Signature(property) => Property::Signature(chain(first, property)), Property::Timestamp(property) => Property::Timestamp(chain(first, property)), @@ -138,7 +135,7 @@ impl<'a, I: 'a> Property<'a, I> { match self { Property::String(property) => wrap(property), Property::Boolean(property) => wrap(property), - Property::CommitOrChangeId(property, _) => wrap(property), + Property::CommitOrChangeId(property) => wrap(property), Property::Signature(property) => wrap(property), Property::Timestamp(property) => wrap(property), } @@ -171,8 +168,8 @@ fn parse_method_chain<'a, I: 'a>( let (property, mut labels) = match input_property { Property::String(property) => chain(property, || parse_string_method(method)), Property::Boolean(property) => chain(property, || parse_boolean_method(method)), - Property::CommitOrChangeId(property, repo) => { - chain(property, || parse_commit_or_change_id_method(method, repo)) + Property::CommitOrChangeId(property) => { + chain(property, || parse_commit_or_change_id_method(method)) } Property::Signature(property) => chain(property, || parse_signature_method(method)), Property::Timestamp(property) => chain(property, || parse_timestamp_method(method)), @@ -207,8 +204,7 @@ fn parse_boolean_method<'a>(method: Pair) -> PropertyAndLabels<'a, bool> { fn parse_commit_or_change_id_method<'a>( method: Pair, - repo: RepoRef<'a>, -) -> PropertyAndLabels<'a, CommitOrChangeId> { +) -> PropertyAndLabels<'a, CommitOrChangeId<'a>> { assert_eq!(method.as_rule(), Rule::method); let mut inner = method.into_inner(); let name = inner.next().unwrap(); @@ -217,7 +213,7 @@ fn parse_commit_or_change_id_method<'a>( let this_function = match name.as_str() { "short" => Property::String(Box::new(CommitOrChangeIdShort)), "short_prefix_and_brackets" => { - Property::String(Box::new(CommitOrChangeIdShortPrefixAndBrackets { repo })) + Property::String(Box::new(CommitOrChangeIdShortPrefixAndBrackets)) } name => panic!("no such commit ID method: {name}"), }; @@ -265,8 +261,8 @@ fn parse_commit_keyword<'a>( assert_eq!(pair.as_rule(), Rule::identifier); let property = match pair.as_str() { "description" => Property::String(Box::new(DescriptionProperty)), - "change_id" => Property::CommitOrChangeId(Box::new(ChangeIdProperty), repo), - "commit_id" => Property::CommitOrChangeId(Box::new(CommitIdProperty), repo), + "change_id" => Property::CommitOrChangeId(Box::new(ChangeIdProperty { repo })), + "commit_id" => Property::CommitOrChangeId(Box::new(CommitIdProperty { repo })), "author" => Property::Signature(Box::new(AuthorProperty)), "committer" => Property::Signature(Box::new(CommitterProperty)), "working_copies" => Property::String(Box::new(WorkingCopiesProperty { repo })), diff --git a/src/templater.rs b/src/templater.rs index 5c4022558..a1a2f9504 100644 --- a/src/templater.rs +++ b/src/templater.rs @@ -451,16 +451,19 @@ impl<'a, C, I, O> TemplateProperty for TemplateFunction<'a, C, I, O> { } /// Type-erased `CommitId`/`ChangeId`. -#[derive(Debug, Clone)] -pub struct CommitOrChangeId(Vec); +#[derive(Clone)] +pub struct CommitOrChangeId<'a> { + repo: RepoRef<'a>, + id_bytes: Vec, +} -impl CommitOrChangeId { +impl CommitOrChangeId<'_> { pub fn as_bytes(&self) -> &[u8] { - &self.0 + &self.id_bytes } pub fn hex(&self) -> String { - hex::encode(&self.0) + hex::encode(&self.id_bytes) } pub fn short(&self) -> String { @@ -469,19 +472,20 @@ impl CommitOrChangeId { hex } - pub fn short_prefix_and_brackets(&self, repo: RepoRef) -> String { - highlight_shortest_prefix(self, 12, repo) + pub fn short_prefix_and_brackets(&self) -> String { + highlight_shortest_prefix(self, 12) } } -impl Template<()> for CommitOrChangeId { +impl Template<()> for CommitOrChangeId<'_> { fn format(&self, _: &(), formatter: &mut dyn Formatter) -> io::Result<()> { formatter.write_str(&self.hex()) } } -fn highlight_shortest_prefix(id: &CommitOrChangeId, total_len: usize, repo: RepoRef) -> String { - let prefix_len = repo +fn highlight_shortest_prefix(id: &CommitOrChangeId, total_len: usize) -> String { + let prefix_len = id + .repo .base_repo() .shortest_unique_prefix_length(id.as_bytes()); let mut hex = id.hex(); @@ -499,7 +503,7 @@ fn highlight_shortest_prefix(id: &CommitOrChangeId, total_len: usize, repo: Repo pub struct CommitOrChangeIdShort; -impl TemplateProperty for CommitOrChangeIdShort { +impl TemplateProperty> for CommitOrChangeIdShort { type Output = String; fn extract(&self, context: &CommitOrChangeId) -> Self::Output { @@ -507,35 +511,43 @@ impl TemplateProperty for CommitOrChangeIdShort { } } -pub struct CommitOrChangeIdShortPrefixAndBrackets<'a> { - pub repo: RepoRef<'a>, -} +pub struct CommitOrChangeIdShortPrefixAndBrackets; -impl TemplateProperty for CommitOrChangeIdShortPrefixAndBrackets<'_> { +impl TemplateProperty> for CommitOrChangeIdShortPrefixAndBrackets { type Output = String; fn extract(&self, context: &CommitOrChangeId) -> Self::Output { - context.short_prefix_and_brackets(self.repo) + context.short_prefix_and_brackets() } } -pub struct CommitIdProperty; +pub struct CommitIdProperty<'a> { + pub repo: RepoRef<'a>, +} -impl TemplateProperty for CommitIdProperty { - type Output = CommitOrChangeId; +impl<'a> TemplateProperty for CommitIdProperty<'a> { + type Output = CommitOrChangeId<'a>; fn extract(&self, context: &Commit) -> Self::Output { - CommitOrChangeId(context.id().to_bytes()) + CommitOrChangeId { + repo: self.repo, + id_bytes: context.id().to_bytes(), + } } } -pub struct ChangeIdProperty; +pub struct ChangeIdProperty<'a> { + pub repo: RepoRef<'a>, +} -impl TemplateProperty for ChangeIdProperty { - type Output = CommitOrChangeId; +impl<'a> TemplateProperty for ChangeIdProperty<'a> { + type Output = CommitOrChangeId<'a>; fn extract(&self, context: &Commit) -> Self::Output { - CommitOrChangeId(context.change_id().to_bytes()) + CommitOrChangeId { + repo: self.repo, + id_bytes: context.change_id().to_bytes(), + } } }