代码之家  ›  专栏  ›  技术社区  ›  Dinaiscoding

使用Serde反序列化strum枚举时出错

  •  0
  • Dinaiscoding  · 技术社区  · 2 年前

    伙计们,我陷入了一个非常简单的问题 strum serde 板条箱是锈的。 首先,我在下面有一个结构:

    use enums::Timezone;
    use crate::CustomError;
    use serde::{Deserialize, Serialize};
    use serde_json::{from_str, to_string};
    
    #[derive(Clone, Deserialize, Serialize, Debug, PartialEq)]
    #[serde(rename_all = "snake_case")]
    pub struct LocaleConfig {
        pub timezone: Timezone,
        pub language: String,
    }
    impl LocaleConfig {
        fn from_json_str(json_str: &str) -> Result<Self, CustomError> {
            from_str(json_str)?
        }
    

    正如你所看到的,我正在使用 Timezone 枚举如下:

    use serde::{Deserialize, Serialize};
    use strum_macros::{Display, EnumIter, EnumString};
    #[derive(Clone, Copy, Deserialize, Serialize, Debug, PartialEq, EnumString, EnumIter, Display)]
    pub enum Timezone {
        #[serde(rename = "GMT-12")]
        #[strum(serialize = "GMT-12")]
        UTCm12,
        #[serde(rename = "GMT-11")]
        #[strum(serialize = "GMT-11")]
        UTCm11,
    ...
        #[serde(rename = "GMT+11")]
        #[strum(serialize = "GMT+11")]
        UTCp11,
        #[serde(rename = "GMT+12")]
        #[strum(serialize = "GMT+12")]
        UTCp12,
    }
    

    问题是,当我尝试反序列化时:

    let json = r#"{"timezone":"GMT-5","language":"en-US"}"#;
    

    具有 LocaleConfig::from_json_str 我得到以下错误:

    Custom Error { title: "Serde Json Error", description: "unknown variant `timezone`, expected `Ok` or `Err` at line 1 column 11" }
    

    正如你所推断的, CustomError 只是包装我的板条箱错误。此外,请注意 LocaleConfig 时区 位于不同的模块中。

    enums/货物.toml

    [package]
    name = "enums"
    
    [dependencies]
    serde = { workspace = true }
    serde_json = { workspace = true }
    strum = { version = "0.26.2" }
    strum_macros = { version = "0.26.2" }
    

    配置/货物.toml

    [package]
    name = "config"
    [dependencies]
    serde = { workspace = true, features = ["derive"] }
    serde_json = { workspace = true }
    enums = { workspace = true }
    

    最后,我的虚拟清单使用以下版本:

    [workspace.dependencies.serde]
    serde = { version = "1.0.197", features = ["derive"] }
    
    [workspace.dependencies.serde_json]
    version = "1.0.114"
    

    我在这里错过了什么?我的意思是,当我跑步时: Timezone::from_str("GMT-5"); ,我答对了 enum ,但我知道 desererialize fn 正在运行可能会有所不同。

    对这件事有什么见解吗?

    1 回复  |  直到 2 年前
        1
  •  2
  •   BallpointBen    2 年前

    你的问题是如何称呼它:

    fn from_json_str(json_str: &str) -> Result<Self, CustomError> {
        from_str(json_str)?
    }
    

    from_str(json_str) 返回一个 Result<T, Error> 哪里 T 将根据上下文确定。 from_str(json_str)? 将提前返回并返回错误(如果有),否则将传递中的值 Ok 变种中的值 好啊 变体(所以不是外部 Result ,而是其类型的实例 T )是从该函数返回的内容,因此 必须是 Result<Self, Error> ,也就是说,您无意中告诉serde您正在反序列化为 结果<自我,错误> , Self 。(或者等效地说 from_str 是返回 Result<Result<Self, Error>, Error> .)

    要解决此问题,请编写 Ok(from_str(json_str)?) 自从 好的(from_str(json_str)?) 必须具有类型 结果<自我,错误> , from_str(json_str)? 必须具有类型 自己 .

    推荐文章