Repository: bottlerocket-os/bottlerocket
File: sources/settings-migrations/v1.40.0/kubelet-device-plugins-cdi-settings/src/main.rs (Rust)

Code before:
    fn forward(&mut self, input: MigrationData) -> Result<MigrationData> {
        println!("ReplaceDeviceListStrategy has no work to do on upgrade.",);
        Ok(input)
    }

    /// Older versions don't know about the settings; we remove them so that old versions don't see
    /// them and fail deserialization.  (The settings must be defaulted or generated in new versions,
    /// and safe to remove.)
    fn backward(&mut self, mut input: MigrationData) -> Result<MigrationData> {
        let setting = DEVICE_LIST_STRATEGY_SETTING;
        if let Some(data) = input.data.get_mut(setting) {
            match data {
                serde_json::Value::Array(arr) => {
                    let list: Vec<&str> = arr
                        .iter()
                        .map(|v| v.as_str())
                        .collect::<Option<Vec<&str>>>()
                        .context(error::ReplaceListContentsSnafu {
                            setting,
                            data: arr.clone(),
                        })?;

                    let new_value = if list.is_empty() || list[0] == "cdi-cri" {
                        "volume-mounts".to_string()
                    } else {
                        list[0].to_string()
                    };

                    *data = serde_json::Value::String(new_value.to_string());
                }

                serde_json::Value::String(setting_str) => {
                    if setting_str == "cdi-cri" {
                        *data = serde_json::Value::String("volume-mounts".to_string());
                    } else {
                        *data = serde_json::Value::String(setting_str.to_string());
                    }
                }

                _ => error::InvalidSettingTypeSnafu {
                    data: setting.to_string(),
                }
                .fail()?,
            }
        } else {
            println!("Found no '{}' to change on downgrade", setting);
        }

        Ok(input)
    }
}

Review comment (suggestion):
This is mostly a coding style preference:

Vec has util function [first](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.first) which is the more "idiomatic" way to get the first item so that we don't need to use [0]. 

This blob can be:

```suggestion
                    let new_value = match list.first() {
                         None | Some(&"cdi-cri") => "volume-mounts".to_string(),
                         Some(value) => value.to_string(),
                     };          
```



Code after:
    fn forward(&mut self, input: MigrationData) -> Result<MigrationData> {
        println!("ReplaceDeviceListStrategy has no work to do on upgrade.");
        Ok(input)
    }

    /// Older versions don't know about the setting now accepting both a string, a list and a new accepted value "cdi-cri";
    /// we remove the list option and the "cdi-cri" value so that old versions don't see them and fail deserialization.
    /// (The settings must be defaulted or generated in new versions, and safe to remove.)
    fn backward(&mut self, mut input: MigrationData) -> Result<MigrationData> {
        let setting = DEVICE_LIST_STRATEGY_SETTING;
        if let Some(data) = input.data.get_mut(setting) {
            match data {
                serde_json::Value::Array(arr) => {
                    let list: Vec<&str> = arr
                        .iter()
                        .map(|v| v.as_str())
                        .collect::<Option<Vec<&str>>>()
                        .context(error::ReplaceListContentsSnafu {
                            setting,
                            data: arr.clone(),
                        })?;

                    let new_value = match list.first() {
                        None | Some(&"cdi-cri") => "volume-mounts".to_string(),
                        Some(value) => value.to_string(),
                    };

                    *data = serde_json::Value::String(new_value.to_string());
                }

                serde_json::Value::String(setting_str) => {
                    if setting_str == "cdi-cri" {
                        *data = serde_json::Value::String("volume-mounts".to_string());
                    } else {
                        *data = serde_json::Value::String(setting_str.to_string());
                    }
                }

                _ => error::InvalidSettingTypeSnafu {
                    data: setting.to_string(),
                }
                .fail()?,
            }
        } else {
            println!("Found no '{}' to change on downgrade", setting);
        }

        Ok(input)
    }
}