History

commit_templater: teach elidable (or optional) commit

I think Option<Commit> is the simplest encoding of the log node. The behavior of an Option type is closer to nullable types rather than the Option in Rust. I don't think we would want to write opt.map(|x| x.f()) or opt.unwrap().f(). We can of course add opt?.f() syntax, but it will be a short for "if(opt, opt.f())"?

Yuya Nishihara committed 2 years ago

Commit 2fc7feb1 parent 2afd3412 files · +26 −1Browse files

Showing the changes to cli/src (1 of 2 files). Show all

Unified · Split

cli/src/commit_templater.rs+20−1
@@ -39,7 +39,7 @@ use crate::template_builder::{ · 38 unmodified lines
39use crate::template_parser::{self, FunctionCallNode, TemplateParseError, TemplateParseResult};39use crate::template_parser::{self, FunctionCallNode, TemplateParseError, TemplateParseResult};
40use crate::templater::{40use crate::templater::{
41 self, IntoTemplate, PlainTextFormattedProperty, Template, TemplateProperty,41 self, IntoTemplate, PlainTextFormattedProperty, Template, TemplateProperty,
42 TemplatePropertyExt as _,42 TemplatePropertyError, TemplatePropertyExt as _,
43};43};
44use crate::{revset_util, text_util};44use crate::{revset_util, text_util};
45 45
@@ -126,6 +126,14 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> { · 80 unmodified lines
126 let build = template_parser::lookup_method("Commit", table, function)?;126 let build = template_parser::lookup_method("Commit", table, function)?;
127 build(self, build_ctx, property, function)127 build(self, build_ctx, property, function)
128 }128 }
129 CommitTemplatePropertyKind::CommitOpt(property) => {
130 let table = &self.build_fn_table.commit_methods;
131 let build = template_parser::lookup_method("Commit", table, function)?;
132 let inner_property = property.and_then(|opt| {
133 opt.ok_or_else(|| TemplatePropertyError("No commit available".into()))
134 });
135 build(self, build_ctx, Box::new(inner_property), function)
136 }
129 CommitTemplatePropertyKind::CommitList(property) => {137 CommitTemplatePropertyKind::CommitList(property) => {
130 // TODO: migrate to table?138 // TODO: migrate to table?
131 template_builder::build_unformattable_list_method(139 template_builder::build_unformattable_list_method(
@@ -190,6 +198,12 @@ impl<'repo> CommitTemplateLanguage<'repo> { · 58 unmodified lines
190 CommitTemplatePropertyKind::Commit(Box::new(property))198 CommitTemplatePropertyKind::Commit(Box::new(property))
191 }199 }
192 200
201 pub fn wrap_commit_opt(
202 property: impl TemplateProperty<Output = Option<Commit>> + 'repo,
203 ) -> CommitTemplatePropertyKind<'repo> {
204 CommitTemplatePropertyKind::CommitOpt(Box::new(property))
205 }
206
193 pub fn wrap_commit_list(207 pub fn wrap_commit_list(
194 property: impl TemplateProperty<Output = Vec<Commit>> + 'repo,208 property: impl TemplateProperty<Output = Vec<Commit>> + 'repo,
195 ) -> CommitTemplatePropertyKind<'repo> {209 ) -> CommitTemplatePropertyKind<'repo> {
@@ -224,6 +238,7 @@ impl<'repo> CommitTemplateLanguage<'repo> { · 28 unmodified lines
224pub enum CommitTemplatePropertyKind<'repo> {238pub enum CommitTemplatePropertyKind<'repo> {
225 Core(CoreTemplatePropertyKind<'repo>),239 Core(CoreTemplatePropertyKind<'repo>),
226 Commit(Box<dyn TemplateProperty<Output = Commit> + 'repo>),240 Commit(Box<dyn TemplateProperty<Output = Commit> + 'repo>),
241 CommitOpt(Box<dyn TemplateProperty<Output = Option<Commit>> + 'repo>),
227 CommitList(Box<dyn TemplateProperty<Output = Vec<Commit>> + 'repo>),242 CommitList(Box<dyn TemplateProperty<Output = Vec<Commit>> + 'repo>),
228 RefName(Box<dyn TemplateProperty<Output = RefName> + 'repo>),243 RefName(Box<dyn TemplateProperty<Output = RefName> + 'repo>),
229 RefNameList(Box<dyn TemplateProperty<Output = Vec<RefName>> + 'repo>),244 RefNameList(Box<dyn TemplateProperty<Output = Vec<RefName>> + 'repo>),
@@ -236,6 +251,9 @@ impl<'repo> IntoTemplateProperty<'repo> for CommitTemplatePropertyKind<'repo> { · 6 unmodified lines
236 match self {251 match self {
237 CommitTemplatePropertyKind::Core(property) => property.try_into_boolean(),252 CommitTemplatePropertyKind::Core(property) => property.try_into_boolean(),
238 CommitTemplatePropertyKind::Commit(_) => None,253 CommitTemplatePropertyKind::Commit(_) => None,
254 CommitTemplatePropertyKind::CommitOpt(property) => {
255 Some(Box::new(property.map(|opt| opt.is_some())))
256 }
239 CommitTemplatePropertyKind::CommitList(property) => {257 CommitTemplatePropertyKind::CommitList(property) => {
240 Some(Box::new(property.map(|l| !l.is_empty())))258 Some(Box::new(property.map(|l| !l.is_empty())))
241 }259 }
@@ -269,6 +287,7 @@ impl<'repo> IntoTemplateProperty<'repo> for CommitTemplatePropertyKind<'repo> { · 27 unmodified lines
269 match self {287 match self {
270 CommitTemplatePropertyKind::Core(property) => property.try_into_template(),288 CommitTemplatePropertyKind::Core(property) => property.try_into_template(),
271 CommitTemplatePropertyKind::Commit(_) => None,289 CommitTemplatePropertyKind::Commit(_) => None,
290 CommitTemplatePropertyKind::CommitOpt(_) => None,
272 CommitTemplatePropertyKind::CommitList(_) => None,291 CommitTemplatePropertyKind::CommitList(_) => None,
273 CommitTemplatePropertyKind::RefName(property) => Some(property.into_template()),292 CommitTemplatePropertyKind::RefName(property) => Some(property.into_template()),
274 CommitTemplatePropertyKind::RefNameList(property) => Some(property.into_template()),293 CommitTemplatePropertyKind::RefNameList(property) => Some(property.into_template()),