From 944bf326eede828f97f1d64d6bb897bd326aa241 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sun, 12 Oct 2025 01:51:25 -0400 Subject: [PATCH] refactor(gctx): extract error to a module --- src/cargo/util/context/error.rs | 108 ++++++++++++++++++++++++++++++++ src/cargo/util/context/mod.rs | 102 +----------------------------- 2 files changed, 111 insertions(+), 99 deletions(-) create mode 100644 src/cargo/util/context/error.rs diff --git a/src/cargo/util/context/error.rs b/src/cargo/util/context/error.rs new file mode 100644 index 00000000000..fe7f3ad497b --- /dev/null +++ b/src/cargo/util/context/error.rs @@ -0,0 +1,108 @@ +use std::fmt; + +use crate::util::ConfigValue; +use crate::util::context::ConfigKey; +use crate::util::context::Definition; + +/// Internal error for serde errors. +#[derive(Debug)] +pub struct ConfigError { + error: anyhow::Error, + definition: Option, +} + +impl ConfigError { + pub(super) fn new(message: String, definition: Definition) -> ConfigError { + ConfigError { + error: anyhow::Error::msg(message), + definition: Some(definition), + } + } + + pub(super) fn expected(key: &ConfigKey, expected: &str, found: &ConfigValue) -> ConfigError { + ConfigError { + error: anyhow::anyhow!( + "`{}` expected {}, but found a {}", + key, + expected, + found.desc() + ), + definition: Some(found.definition().clone()), + } + } + + pub(super) fn is_missing_field(&self) -> bool { + self.error.downcast_ref::().is_some() + } + + pub(super) fn missing(key: &ConfigKey) -> ConfigError { + ConfigError { + error: anyhow::anyhow!("missing config key `{}`", key), + definition: None, + } + } + + pub(super) fn with_key_context( + self, + key: &ConfigKey, + definition: Option, + ) -> ConfigError { + ConfigError { + error: anyhow::Error::from(self) + .context(format!("could not load config key `{}`", key)), + definition: definition, + } + } +} + +impl std::error::Error for ConfigError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + self.error.source() + } +} + +impl fmt::Display for ConfigError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(definition) = &self.definition { + write!(f, "error in {}: {}", definition, self.error) + } else { + self.error.fmt(f) + } + } +} + +#[derive(Debug)] +struct MissingFieldError(String); + +impl fmt::Display for MissingFieldError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "missing field `{}`", self.0) + } +} + +impl std::error::Error for MissingFieldError {} + +impl serde::de::Error for ConfigError { + fn custom(msg: T) -> Self { + ConfigError { + error: anyhow::Error::msg(msg.to_string()), + definition: None, + } + } + + fn missing_field(field: &'static str) -> Self { + ConfigError { + error: anyhow::Error::new(MissingFieldError(field.to_string())), + definition: None, + } + } +} + +impl From for ConfigError { + fn from(error: anyhow::Error) -> Self { + ConfigError { + error, + definition: None, + } + } +} diff --git a/src/cargo/util/context/mod.rs b/src/cargo/util/context/mod.rs index 7a4831535ed..8f9780ab86d 100644 --- a/src/cargo/util/context/mod.rs +++ b/src/cargo/util/context/mod.rs @@ -96,6 +96,9 @@ use url::Url; mod de; use de::Deserializer; +mod error; +pub use error::ConfigError; + mod value; pub use value::{Definition, OptValue, Value}; @@ -2052,105 +2055,6 @@ impl GlobalContext { } } -/// Internal error for serde errors. -#[derive(Debug)] -pub struct ConfigError { - error: anyhow::Error, - definition: Option, -} - -impl ConfigError { - fn new(message: String, definition: Definition) -> ConfigError { - ConfigError { - error: anyhow::Error::msg(message), - definition: Some(definition), - } - } - - fn expected(key: &ConfigKey, expected: &str, found: &ConfigValue) -> ConfigError { - ConfigError { - error: anyhow!( - "`{}` expected {}, but found a {}", - key, - expected, - found.desc() - ), - definition: Some(found.definition().clone()), - } - } - - fn is_missing_field(&self) -> bool { - self.error.downcast_ref::().is_some() - } - - fn missing(key: &ConfigKey) -> ConfigError { - ConfigError { - error: anyhow!("missing config key `{}`", key), - definition: None, - } - } - - fn with_key_context(self, key: &ConfigKey, definition: Option) -> ConfigError { - ConfigError { - error: anyhow::Error::from(self) - .context(format!("could not load config key `{}`", key)), - definition: definition, - } - } -} - -impl std::error::Error for ConfigError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - self.error.source() - } -} - -impl fmt::Display for ConfigError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some(definition) = &self.definition { - write!(f, "error in {}: {}", definition, self.error) - } else { - self.error.fmt(f) - } - } -} - -#[derive(Debug)] -struct MissingFieldError(String); - -impl fmt::Display for MissingFieldError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "missing field `{}`", self.0) - } -} - -impl std::error::Error for MissingFieldError {} - -impl serde::de::Error for ConfigError { - fn custom(msg: T) -> Self { - ConfigError { - error: anyhow::Error::msg(msg.to_string()), - definition: None, - } - } - - fn missing_field(field: &'static str) -> Self { - ConfigError { - error: anyhow::Error::new(MissingFieldError(field.to_string())), - definition: None, - } - } -} - -impl From for ConfigError { - fn from(error: anyhow::Error) -> Self { - ConfigError { - error, - definition: None, - } - } -} - #[derive(Debug)] enum KeyOrIdx { Key(String),