diff --git a/src/template_parser.rs b/src/template_parser.rs index 462ad2312..3b74e9c59 100644 --- a/src/template_parser.rs +++ b/src/template_parser.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use jujutsu_lib::backend::{CommitId, Signature, Timestamp}; +use jujutsu_lib::backend::{Signature, Timestamp}; use jujutsu_lib::commit::Commit; use jujutsu_lib::op_store::WorkspaceId; use jujutsu_lib::repo::RepoRef; @@ -22,12 +22,12 @@ use pest_derive::Parser; use crate::formatter::PlainTextFormatter; use crate::templater::{ - AuthorProperty, BranchProperty, ChangeIdProperty, CommitIdKeyword, CommitterProperty, - ConditionalTemplate, ConflictProperty, ConstantTemplateProperty, DescriptionProperty, - DivergentProperty, DynamicLabelTemplate, EmptyProperty, GitRefsProperty, IsGitHeadProperty, - IsWorkingCopyProperty, LabelTemplate, ListTemplate, LiteralTemplate, SignatureTimestamp, - StringPropertyTemplate, TagProperty, Template, TemplateFunction, TemplateProperty, - WorkingCopiesProperty, + AuthorProperty, BranchProperty, CommitOrChangeId, CommitOrChangeIdKeyword, + CommitOrChangeIdShortest, CommitterProperty, ConditionalTemplate, ConflictProperty, + ConstantTemplateProperty, DescriptionProperty, DivergentProperty, DynamicLabelTemplate, + EmptyProperty, GitRefsProperty, IsGitHeadProperty, IsWorkingCopyProperty, LabelTemplate, + ListTemplate, LiteralTemplate, SignatureTimestamp, StringPropertyTemplate, TagProperty, + Template, TemplateFunction, TemplateProperty, WorkingCopiesProperty, }; use crate::time_util; @@ -71,14 +71,6 @@ impl TemplateProperty for StringFirstLine { } } -struct CommitIdShortest; - -impl TemplateProperty for CommitIdShortest { - fn extract(&self, context: &CommitId) -> String { - CommitIdKeyword::shortest_format(context.clone()) - } -} - struct SignatureName; impl TemplateProperty for SignatureName { @@ -106,7 +98,7 @@ impl TemplateProperty for RelativeTimestampString { enum Property<'a, I> { String(Box + 'a>), Boolean(Box + 'a>), - CommitId(Box + 'a>), + CommitOrChangeId(Box + 'a>), Signature(Box + 'a>), Timestamp(Box + 'a>), } @@ -122,10 +114,9 @@ impl<'a, I: 'a> Property<'a, I> { first, Box::new(move |value| property.extract(&value)), ))), - Property::CommitId(property) => Property::CommitId(Box::new(TemplateFunction::new( - first, - Box::new(move |value| property.extract(&value)), - ))), + Property::CommitOrChangeId(property) => Property::CommitOrChangeId(Box::new( + TemplateFunction::new(first, Box::new(move |value| property.extract(&value))), + )), Property::Signature(property) => Property::Signature(Box::new(TemplateFunction::new( first, Box::new(move |value| property.extract(&value)), @@ -163,8 +154,9 @@ fn parse_method_chain<'a, I: 'a>( let PropertyAndLabels(next_method, labels) = parse_boolean_method(method); (next_method.after(property), labels) } - Property::CommitId(property) => { - let PropertyAndLabels(next_method, labels) = parse_commit_id_method(method); + Property::CommitOrChangeId(property) => { + let PropertyAndLabels(next_method, labels) = + parse_commit_or_chain_id_method(method); (next_method.after(property), labels) } Property::Signature(property) => { @@ -207,14 +199,16 @@ fn parse_boolean_method<'a>(method: Pair) -> PropertyAndLabels<'a, bool> { // TODO: pass a context to the returned function (we need the repo to find the // shortest unambiguous prefix) -fn parse_commit_id_method<'a>(method: Pair) -> PropertyAndLabels<'a, CommitId> { +fn parse_commit_or_chain_id_method<'a>( + method: Pair, +) -> PropertyAndLabels<'a, CommitOrChangeId> { assert_eq!(method.as_rule(), Rule::method); let mut inner = method.into_inner(); let name = inner.next().unwrap(); // TODO: validate arguments let this_function = match name.as_str() { - "short" => Property::String(Box::new(CommitIdShortest)), + "short" => Property::String(Box::new(CommitOrChangeIdShortest)), name => panic!("no such commit ID method: {name}"), }; let chain_method = inner.last().unwrap(); @@ -261,8 +255,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::String(Box::new(ChangeIdProperty)), - "commit_id" => Property::CommitId(Box::new(CommitIdKeyword)), + "change_id" => Property::CommitOrChangeId(Box::new(CommitOrChangeIdKeyword::change())), + "commit_id" => Property::CommitOrChangeId(Box::new(CommitOrChangeIdKeyword::commit())), "author" => Property::Signature(Box::new(AuthorProperty)), "committer" => Property::Signature(Box::new(CommitterProperty)), "working_copies" => Property::String(Box::new(WorkingCopiesProperty { repo })), @@ -291,9 +285,9 @@ fn coerce_to_string<'a, I: 'a>( property, Box::new(|value| String::from(if value { "true" } else { "false" })), )), - Property::CommitId(property) => Box::new(TemplateFunction::new( + Property::CommitOrChangeId(property) => Box::new(TemplateFunction::new( property, - Box::new(CommitIdKeyword::default_format), + Box::new(CommitOrChangeIdKeyword::default_format), )), Property::Signature(property) => Box::new(TemplateFunction::new( property, diff --git a/src/templater.rs b/src/templater.rs index 82a3bd2ab..1eafb9943 100644 --- a/src/templater.rs +++ b/src/templater.rs @@ -155,14 +155,6 @@ impl<'a, C> Template for StringPropertyTemplate<'a, C> { } } -pub struct ChangeIdProperty; - -impl TemplateProperty for ChangeIdProperty { - fn extract(&self, context: &Commit) -> String { - context.change_id().hex() - } -} - pub struct DescriptionProperty; impl TemplateProperty for DescriptionProperty { @@ -415,22 +407,59 @@ impl<'a, C, I, O> TemplateProperty for TemplateFunction<'a, C, I, O> { } } -pub struct CommitIdKeyword; +#[derive(Debug, Clone)] +pub enum CommitOrChangeId { + CommitId(CommitId), + ChangeId(ChangeId), +} -impl CommitIdKeyword { - pub fn default_format(commit_id: CommitId) -> String { - commit_id.hex() - } - - pub fn shortest_format(commit_id: CommitId) -> String { - // TODO: make this actually be the shortest unambiguous prefix - commit_id.hex()[..12].to_string() +impl CommitOrChangeId { + pub fn hex(&self) -> String { + match self { + CommitOrChangeId::CommitId(id) => id.hex(), + CommitOrChangeId::ChangeId(id) => id.hex(), + } } } -impl TemplateProperty for CommitIdKeyword { - fn extract(&self, context: &Commit) -> CommitId { - context.id().clone() +#[derive(Debug, Clone)] +enum CommitOrChange { + Commit, + Change, +} + +pub struct CommitOrChangeIdKeyword(CommitOrChange); + +impl CommitOrChangeIdKeyword { + pub fn commit() -> Self { + Self(CommitOrChange::Commit) + } + pub fn change() -> Self { + Self(CommitOrChange::Change) + } + pub fn default_format(commit_or_change_id: CommitOrChangeId) -> String { + commit_or_change_id.hex() + } + + pub fn shortest_format(commit_or_change_id: CommitOrChangeId) -> String { + commit_or_change_id.hex()[..12].to_string() + } +} + +pub struct CommitOrChangeIdShortest; + +impl TemplateProperty for CommitOrChangeIdShortest { + fn extract(&self, context: &CommitOrChangeId) -> String { + CommitOrChangeIdKeyword::shortest_format(context.clone()) + } +} + +impl TemplateProperty for CommitOrChangeIdKeyword { + fn extract(&self, context: &Commit) -> CommitOrChangeId { + match &self.0 { + CommitOrChange::Commit => CommitOrChangeId::CommitId(context.id().clone()), + CommitOrChange::Change => CommitOrChangeId::ChangeId(context.change_id().clone()), + } } }