Repository: alacritty/alacritty
File: alacritty_config_derive/src/de_struct.rs (Rust)

Code before:
            Ok(parsed) => parsed,
            Err(_) => continue,
        };

        match parsed.ident.as_str() {
            // Skip deserialization for `#[config(skip)]` fields.
            "skip" => return Ok(()),
            "flatten" => {
                // NOTE: Currently only a single instance of flatten is supported per struct
                // for complexity reasons.
                if !field_streams.flatten.is_empty() {
                    return Err(Error::new(attr.span(), MULTIPLE_FLATTEN_ERROR));
                }

                // Create the tokens to deserialize the flattened struct from the unused fields.
                field_streams.flatten.extend(quote! {
                    let unused = serde_yaml::Value::Mapping(unused);
                    config.#ident = serde::Deserialize::deserialize(unused).unwrap_or_default();
                });
            },
            "deprecated" | "removed" => {
                // Construct deprecation/removal message and append optional attribute override.
                let mut verb = "is";
                if parsed.ident == "removed" {
                    verb = "was";
                }
                let mut message = format!("Config warning: {} {} {}", literal, verb, parsed.ident);
                if let Some(warning) = parsed.param {
                    message = format!("{}; {}", message, warning.value());
                }

                // Append stream to log deprecation/removal warning.
                match_assignment_stream.extend(quote! {
                    log::warn!(target: #LOG_TARGET, #message);
                });
            },
            // Add aliases to match pattern.
            "alias" => {
                if let Some(alias) = parsed.param {
                    literals.push(alias.value());
                }
            },
            _ => (),
        }
    }

    // Create token stream for deserializing "none" string into `Option<T>`.
    if let Type::Path(type_path) = &field.ty {
        if crate::path_ends_with(&type_path.path, "Option") {
            match_assignment_stream = quote! {
                if value.as_str().map_or(false, |s| s.eq_ignore_ascii_case("none")) {

Review comment (suggestion):
```suggestion
                let message = match parsed.ident {
                    "removed" => format!("Config warning: {} was removed", literal),
                    _ => format!("Config warning: {} is deprecated", literal),
                };
```

Could also add an unreachable branch, but I think this is the cleanest solution for now.

This way there's no unnecessary mutable variable that gets overwritten based on a conditional that can be evaluated before the variable is originally defined.

Code after:
            Ok(parsed) => parsed,
            Err(_) => continue,
        };

        match parsed.ident.as_str() {
            // Skip deserialization for `#[config(skip)]` fields.
            "skip" => return Ok(()),
            "flatten" => {
                // NOTE: Currently only a single instance of flatten is supported per struct
                // for complexity reasons.
                if !field_streams.flatten.is_empty() {
                    return Err(Error::new(attr.span(), MULTIPLE_FLATTEN_ERROR));
                }

                // Create the tokens to deserialize the flattened struct from the unused fields.
                field_streams.flatten.extend(quote! {
                    let unused = serde_yaml::Value::Mapping(unused);
                    config.#ident = serde::Deserialize::deserialize(unused).unwrap_or_default();
                });
            },
            "deprecated" | "removed" => {
                // Construct deprecation/removal message with optional attribute override.
                let mut message = format!("Config warning: {} has been {}", literal, parsed.ident);
                if let Some(warning) = parsed.param {
                    message = format!("{}; {}", message, warning.value());
                }

                // Append stream to log deprecation/removal warning.
                match_assignment_stream.extend(quote! {
                    log::warn!(target: #LOG_TARGET, #message);
                });
            },
            // Add aliases to match pattern.
            "alias" => {
                if let Some(alias) = parsed.param {
                    literals.push(alias.value());
                }
            },
            _ => (),
        }
    }

    // Create token stream for deserializing "none" string into `Option<T>`.
    if let Type::Path(type_path) = &field.ty {
        if crate::path_ends_with(&type_path.path, "Option") {
            match_assignment_stream = quote! {
                if value.as_str().map_or(false, |s| s.eq_ignore_ascii_case("none")) {
                    config.#ident = None;
                    continue;
                }
                #match_assignment_stream