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

Unified · Split

2 files
  1. cli/src/commit_templater.rs +20 −1
  2. docs/templates.md +6 −0
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()),
docs/templates.md+6−0
@@ -137,6 +137,12 @@ The following methods are defined. · 136 unmodified lines
137 137
138* `.short([len: Integer]) -> String`138* `.short([len: Integer]) -> String`
139 139
140### Option type
141
142An option can be implicitly converted to `Boolean` denoting whether the
143contained value is set. If set, all methods of the contained value can be
144invoked. If not set, an error will be reported inline on method call.
145
140### RefName type146### RefName type
141 147
142The following methods are defined.148The following methods are defined.