serde - Несколько значений по умолчанию сгруппированы вместе? - PullRequest
0 голосов
/ 13 марта 2020

Я пытаюсь загрузить файл Toml с помощью Serde, он содержит несколько логических значений, я хочу установить их по умолчанию на false, если они не найдены в текстовом файле.

Моя реализация в настоящее время:

#[derive(serde::Deserialize, serde::Serialize)]
#[serde(rename_all="PascalCase")]
pub struct SomeConfigStruct {
     // This one *must* exist, non optional, non defaulted.
    class_name : String, 

    #[serde(default = "default_boolean")]
    parent_in_constructor : bool,

    #[serde(default = "default_boolean")]
    set_user_texts : bool,

    #[serde(default = "default_boolean")]
    singleton : bool, 

    #[serde(default = "default_boolean")]
    use_enum_types : bool,
}

Как мне сделать что-то в строках:

#[derive(serde::Deserialize, serde::Serialize)]
#[serde(rename_all="PascalCase")]
pub struct SomeConfigStruct {
    class_name : String,

    #[serde(type = bool, default = "default_boolean")]
    parent_in_constructor : bool,
    set_user_texts : bool,
    singleton : bool, 
    use_enum_types : bool,
}

[править, новый член в Структуре, чтобы лучше проиллюстрировать то, что мне нужно.]

1 Ответ

1 голос
/ 13 марта 2020

Обновлено для новых ограничений

Я не знаю такого макроса, насколько мне известно, что не существует. Хотя я могу предложить альтернативное решение.

#[derive(serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct SomeConfigStruct {
    class_name: String,

    #[serde(default)]
    #[serde(flatten)]
    defaulting_values: SomeConfigStructDefaulting,
}

#[derive(serde::Deserialize, serde::Serialize)]
#[serde(default)]
pub struct SomeConfigStructDefaulting {
    parent_in_constructor: bool,
    set_user_texts: bool,
    singleton: bool,
    use_enum_types: bool,
}

// This will be called to fill in missing spots in defaulting_values.
// Will also be called, if defaulting_values is missing altogether.
impl Default for SomeConfigStructDefaulting {
    fn default() -> Self {
        let default_boolean = true;
        Self {
            parent_in_constructor: default_boolean,
            set_user_texts: default_boolean,
            singleton: default_boolean,
            use_enum_types: default_boolean,
        }
    }
}

Это точно не уменьшает количество строк, но фиксирует default_boolean к одному значению, если это было вашей главной задачей.

Таким образом, ваше сериализованное представление будет по-прежнему выглядеть так же, и вы можете легко написать оболочки, чтобы не писать some_config_struct.defaulting_values в вашем фактическом коде.

...