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())"?
Unified · Split
| @@ -39,7 +39,7 @@ use crate::template_builder::{ · 38 unmodified lines | ||
| 39 | 39 | use crate::template_parser::{self, FunctionCallNode, TemplateParseError, TemplateParseResult}; |
| 40 | 40 | use crate::templater::{ |
| 41 | 41 | self, IntoTemplate, PlainTextFormattedProperty, Template, TemplateProperty, |
| 42 | − TemplatePropertyExt as _, | |
| 42 | + TemplatePropertyError, TemplatePropertyExt as _, | |
| 43 | 43 | }; |
| 44 | 44 | use crate::{revset_util, text_util}; |
| 45 | 45 | |
| @@ -126,6 +126,14 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> { · 80 unmodified lines | ||
| 126 | 126 | let build = template_parser::lookup_method("Commit", table, function)?; |
| 127 | 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 | 137 | CommitTemplatePropertyKind::CommitList(property) => { |
| 130 | 138 | // TODO: migrate to table? |
| 131 | 139 | template_builder::build_unformattable_list_method( |
| @@ -190,6 +198,12 @@ impl<'repo> CommitTemplateLanguage<'repo> { · 58 unmodified lines | ||
| 190 | 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 | 207 | pub fn wrap_commit_list( |
| 194 | 208 | property: impl TemplateProperty<Output = Vec<Commit>> + 'repo, |
| 195 | 209 | ) -> CommitTemplatePropertyKind<'repo> { |
| @@ -224,6 +238,7 @@ impl<'repo> CommitTemplateLanguage<'repo> { · 28 unmodified lines | ||
| 224 | 238 | pub enum CommitTemplatePropertyKind<'repo> { |
| 225 | 239 | Core(CoreTemplatePropertyKind<'repo>), |
| 226 | 240 | Commit(Box<dyn TemplateProperty<Output = Commit> + 'repo>), |
| 241 | + CommitOpt(Box<dyn TemplateProperty<Output = Option<Commit>> + 'repo>), | |
| 227 | 242 | CommitList(Box<dyn TemplateProperty<Output = Vec<Commit>> + 'repo>), |
| 228 | 243 | RefName(Box<dyn TemplateProperty<Output = RefName> + 'repo>), |
| 229 | 244 | RefNameList(Box<dyn TemplateProperty<Output = Vec<RefName>> + 'repo>), |
| @@ -236,6 +251,9 @@ impl<'repo> IntoTemplateProperty<'repo> for CommitTemplatePropertyKind<'repo> { · 6 unmodified lines | ||
| 236 | 251 | match self { |
| 237 | 252 | CommitTemplatePropertyKind::Core(property) => property.try_into_boolean(), |
| 238 | 253 | CommitTemplatePropertyKind::Commit(_) => None, |
| 254 | + CommitTemplatePropertyKind::CommitOpt(property) => { | |
| 255 | + Some(Box::new(property.map(|opt| opt.is_some()))) | |
| 256 | + } | |
| 239 | 257 | CommitTemplatePropertyKind::CommitList(property) => { |
| 240 | 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 | 287 | match self { |
| 270 | 288 | CommitTemplatePropertyKind::Core(property) => property.try_into_template(), |
| 271 | 289 | CommitTemplatePropertyKind::Commit(_) => None, |
| 290 | + CommitTemplatePropertyKind::CommitOpt(_) => None, | |
| 272 | 291 | CommitTemplatePropertyKind::CommitList(_) => None, |
| 273 | 292 | CommitTemplatePropertyKind::RefName(property) => Some(property.into_template()), |
| 274 | 293 | CommitTemplatePropertyKind::RefNameList(property) => Some(property.into_template()), |
| @@ -137,6 +137,12 @@ The following methods are defined. · 136 unmodified lines | ||
| 137 | 137 | |
| 138 | 138 | * `.short([len: Integer]) -> String` |
| 139 | 139 | |
| 140 | +### Option type | |
| 141 | + | |
| 142 | +An option can be implicitly converted to `Boolean` denoting whether the | |
| 143 | +contained value is set. If set, all methods of the contained value can be | |
| 144 | +invoked. If not set, an error will be reported inline on method call. | |
| 145 | + | |
| 140 | 146 | ### RefName type |
| 141 | 147 | |
| 142 | 148 | The following methods are defined. |