Repository: starship/starship
File: src/serde_utils.rs (Rust)

Code before:

impl<'de> ValueDeserializer<'de> {
    pub fn new(value: &'de Value) -> Self {
        ValueDeserializer {
            value,
            info: None,
            current_key: None,
            error_on_ignored: true,
        }
    }

    fn with_info(
        value: &'de Value,
        info: Option<StructInfo>,
        current_key: &'de str,
        ignored: bool,
    ) -> Self {
        ValueDeserializer {
            value,
            info,
            current_key: Some(current_key),
            error_on_ignored: ignored,
        }
    }

    pub fn with_no_ignored_error(self) -> Self {
        ValueDeserializer {
            value: self.value,
            info: self.info,
            current_key: self.current_key,
            error_on_ignored: false,
        }
    }
}

impl ValueDeserializer<'_> {
    /// Prettify an error message by adding the current key and struct name to it.
    fn error<T: fmt::Display>(&self, msg: T) -> ValueError {
        match (self.current_key, self.info) {
            (Some(key), Some(StructInfo { name, .. })) => {
                // Prettify name of struct
                let display_name = name.strip_suffix("Config").unwrap_or(name);
                ValueError::custom(format!("Error in '{display_name}' at '{key}': {msg}",))
            }
            // Handling other cases leads to duplicates in the error message.
            _ => ValueError::custom(msg),
        }
    }
}

impl<'de> IntoDeserializer<'de> for ValueDeserializer<'de> {

Review comment (suggestion):
Please find a better name for this function, the current name sounds a bit like it would make the deserializer not ignore errors.

Code after:

impl<'de> ValueDeserializer<'de> {
    pub fn new(value: &'de Value) -> Self {
        ValueDeserializer {
            value,
            info: None,
            current_key: None,
            error_on_ignored: true,
        }
    }

    fn with_info(
        value: &'de Value,
        info: Option<StructInfo>,
        current_key: &'de str,
        ignored: bool,
    ) -> Self {
        ValueDeserializer {
            value,
            info,
            current_key: Some(current_key),
            error_on_ignored: ignored,
        }
    }

    pub fn with_allow_unknown_keys(self) -> Self {
        ValueDeserializer {
            error_on_ignored: false,
            ..self
        }
    }
}

impl ValueDeserializer<'_> {
    /// Prettify an error message by adding the current key and struct name to it.
    fn error<T: fmt::Display>(&self, msg: T) -> ValueError {
        match (self.current_key, self.info) {
            (Some(key), Some(StructInfo { name, .. })) => {
                // Prettify name of struct
                let display_name = name.strip_suffix("Config").unwrap_or(name);
                ValueError::custom(format!("Error in '{display_name}' at '{key}': {msg}",))
            }
            // Handling other cases leads to duplicates in the error message.
            _ => ValueError::custom(msg),
        }
    }
}

impl<'de> IntoDeserializer<'de> for ValueDeserializer<'de> {
    type Deserializer = ValueDeserializer<'de>;