Mercurial > hg
changeset 50981:58390f59826f
rust-config: fix fallback to default not parsing the default value
When a config item's default is a string, it sometimes needs to be parsed
into another type, like in the case of `cmdserver.max-log-size`, that returns
a number of bytes from a human-readable amount like `25MB`.
The logic for the fix is explained inline.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Wed, 09 Aug 2023 15:41:18 +0200 |
parents | d7b2701f17fa |
children | 10e57e3f7276 |
files | rust/hg-core/src/config/config_items.rs rust/hg-core/src/config/mod.rs |
diffstat | 2 files changed, 58 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/config/config_items.rs Tue Aug 08 14:14:00 2023 +0200 +++ b/rust/hg-core/src/config/config_items.rs Wed Aug 09 15:41:18 2023 +0200 @@ -140,6 +140,39 @@ } } +impl<'a> TryFrom<&'a DefaultConfigItem> for Option<&'a [u8]> { + type Error = HgError; + + fn try_from( + value: &'a DefaultConfigItem, + ) -> Result<Option<&'a [u8]>, Self::Error> { + match &value.default { + Some(default) => { + let err = HgError::abort( + format!( + "programming error: wrong query on config item '{}.{}'", + value.section, + value.name + ), + exit_codes::ABORT, + Some(format!( + "asked for bytes, type of default is '{}', \ + which cannot be interpreted as bytes", + default.type_str() + )), + ); + match default { + DefaultConfigItemType::Primitive(p) => { + Ok(p.as_str().map(str::as_bytes)) + } + _ => Err(err), + } + } + None => Ok(None), + } + } +} + impl TryFrom<&DefaultConfigItem> for Option<bool> { type Error = HgError;
--- a/rust/hg-core/src/config/mod.rs Tue Aug 08 14:14:00 2023 +0200 +++ b/rust/hg-core/src/config/mod.rs Wed Aug 09 15:41:18 2023 +0200 @@ -422,7 +422,30 @@ return Ok(None); } match self.get_default(section, item)? { - Some(default) => Ok(default.try_into()?), + Some(default) => { + // Defaults are TOML values, so they're not in the same + // shape as in the config files. + // First try to convert directly to the expected type + let as_t = default.try_into(); + match as_t { + Ok(t) => Ok(t), + Err(e) => { + // If it fails, it means that... + let as_bytes: Result<Option<&[u8]>, _> = + default.try_into(); + match as_bytes { + Ok(bytes_opt) => { + if let Some(bytes) = bytes_opt { + // ...we should be able to parse it + return Ok(parse(bytes)); + } + Err(e) + } + Err(_) => Err(e), + } + } + } + } None => { self.print_devel_warning(section, item)?; Ok(None) @@ -779,7 +802,6 @@ let config = Config::load_from_explicit_sources(vec![]) .expect("expected valid config"); let ret = config.get_byte_size(b"cmdserver", b"max-log-size"); - // FIXME should be `is_ok` - assert!(ret.is_err(), "{:?}", ret); + assert!(ret.is_ok(), "{:?}", ret); } }