# HG changeset patch # User Raphaël Gomès # Date 1676308308 -3600 # Node ID 8ff187fbbfeadcaceed8c37d400f5ced9055140f # Parent f8412da86d0518ccfa03f90d3f97ec615b64e9ba rust-config: add config getters that don't fall back to defaults This is useful in cases where we access config items that are more... lenient with their types than a fresh new system would allow. For now there is only a single use of this, but we might get more later. diff -r f8412da86d05 -r 8ff187fbbfea rust/hg-core/src/config/mod.rs --- a/rust/hg-core/src/config/mod.rs Thu Jul 06 14:32:07 2023 +0200 +++ b/rust/hg-core/src/config/mod.rs Mon Feb 13 18:11:48 2023 +0100 @@ -360,21 +360,21 @@ self.plain = plain; } - /// Returns the default value for the given config item, if any. - pub fn get_default( - &self, - section: &[u8], - item: &[u8], - ) -> Result, HgError> { - let default_config = DEFAULT_CONFIG.as_ref().map_err(|e| { - HgError::abort( - e.to_string(), - crate::exit_codes::ABORT, - Some("`mercurial/configitems.toml` is not valid".into()), - ) - })?; - Ok(default_config.get(section, item)) - } + /// Returns the default value for the given config item, if any. + pub fn get_default( + &self, + section: &[u8], + item: &[u8], + ) -> Result, HgError> { + let default_config = DEFAULT_CONFIG.as_ref().map_err(|e| { + HgError::abort( + e.to_string(), + crate::exit_codes::ABORT, + Some("`mercurial/configitems.toml` is not valid".into()), + ) + })?; + Ok(default_config.get(section, item)) + } fn get_parse<'config, T: 'config>( &'config self, @@ -382,6 +382,7 @@ item: &[u8], expected_type: &'static str, parse: impl Fn(&'config [u8]) -> Option, + fallback_to_default: bool, ) -> Result, HgError> where Option: TryFrom<&'config DefaultConfigItem, Error = HgError>, @@ -399,12 +400,15 @@ }) .into()), }, - None => match self.get_default(section, item)? { - Some(default) => Ok(default.try_into()?), - None => { - Ok(None) + None => { + if !fallback_to_default { + return Ok(None); } - }, + match self.get_default(section, item)? { + Some(default) => Ok(default.try_into()?), + None => Ok(None), + } + } } } @@ -415,9 +419,29 @@ section: &[u8], item: &[u8], ) -> Result, HgError> { - self.get_parse(section, item, "ASCII or UTF-8 string", |value| { - str::from_utf8(value).ok() - }) + self.get_parse( + section, + item, + "ASCII or UTF-8 string", + |value| str::from_utf8(value).ok(), + true, + ) + } + + /// Same as `get_str`, but doesn't fall back to the default `configitem` + /// if not defined in the user config. + pub fn get_str_no_default( + &self, + section: &[u8], + item: &[u8], + ) -> Result, HgError> { + self.get_parse( + section, + item, + "ASCII or UTF-8 string", + |value| str::from_utf8(value).ok(), + false, + ) } /// Returns an `Err` if the first value found is not a valid unsigned @@ -427,9 +451,13 @@ section: &[u8], item: &[u8], ) -> Result, HgError> { - self.get_parse(section, item, "valid integer", |value| { - str::from_utf8(value).ok()?.parse().ok() - }) + self.get_parse( + section, + item, + "valid integer", + |value| str::from_utf8(value).ok()?.parse().ok(), + true, + ) } /// Returns an `Err` if the first value found is not a valid file size @@ -440,7 +468,13 @@ section: &[u8], item: &[u8], ) -> Result, HgError> { - self.get_parse(section, item, "byte quantity", values::parse_byte_size) + self.get_parse( + section, + item, + "byte quantity", + values::parse_byte_size, + true, + ) } /// Returns an `Err` if the first value found is not a valid boolean. @@ -451,7 +485,17 @@ section: &[u8], item: &[u8], ) -> Result, HgError> { - self.get_parse(section, item, "boolean", values::parse_bool) + self.get_parse(section, item, "boolean", values::parse_bool, true) + } + + /// Same as `get_option`, but doesn't fall back to the default `configitem` + /// if not defined in the user config. + pub fn get_option_no_default( + &self, + section: &[u8], + item: &[u8], + ) -> Result, HgError> { + self.get_parse(section, item, "boolean", values::parse_bool, false) } /// Returns the corresponding boolean in the config. Returns `Ok(false)` @@ -464,6 +508,16 @@ Ok(self.get_option(section, item)?.unwrap_or(false)) } + /// Same as `get_bool`, but doesn't fall back to the default `configitem` + /// if not defined in the user config. + pub fn get_bool_no_default( + &self, + section: &[u8], + item: &[u8], + ) -> Result { + Ok(self.get_option_no_default(section, item)?.unwrap_or(false)) + } + /// Returns `true` if the extension is enabled, `false` otherwise pub fn is_extension_enabled(&self, extension: &[u8]) -> bool { let value = self.get(b"extensions", extension); diff -r f8412da86d05 -r 8ff187fbbfea rust/rhg/src/main.rs --- a/rust/rhg/src/main.rs Thu Jul 06 14:32:07 2023 +0200 +++ b/rust/rhg/src/main.rs Mon Feb 13 18:11:48 2023 +0100 @@ -86,7 +86,8 @@ // Mercurial allows users to define generic hooks for commands, // fallback if any are detected let item = format!("{}-{}", prefix, subcommand_name); - let hook_for_command = config.get_str(b"hooks", item.as_bytes())?; + let hook_for_command = + config.get_str_no_default(b"hooks", item.as_bytes())?; if hook_for_command.is_some() { let msg = format!("{}-{} hook defined", prefix, subcommand_name); return Err(CommandError::unsupported(msg));