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())"?
Showing the changes to cli/src (1 of 2 files). Show all
Unified · Split
| @@ -39,7 +39,7 @@ use crate::template_builder::{ · 38 unmodified lines | |||
| 39 | use crate::template_parser::{self, FunctionCallNode, TemplateParseError, TemplateParseResult}; | 39 | use crate::template_parser::{self, FunctionCallNode, TemplateParseError, TemplateParseResult}; |
| 40 | use crate::templater::{ | 40 | use crate::templater::{ |
| 41 | self, IntoTemplate, PlainTextFormattedProperty, Template, TemplateProperty, | 41 | self, IntoTemplate, PlainTextFormattedProperty, Template, TemplateProperty, |
| 42 | TemplatePropertyExt as _, | 42 | TemplatePropertyError, TemplatePropertyExt as _, |
| 43 | }; | 43 | }; |
| 44 | use crate::{revset_util, text_util}; | 44 | use 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 | |||
| 224 | pub enum CommitTemplatePropertyKind<'repo> { | 238 | pub 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()), |