为 serde_json 反序列化制作我自己的错误

Tim*_*ott 5 rust

我正在尝试使用 serde_json 将具有预先存在的格式的 JSON 文件反序列化为我自己的 Rust 文件。

我想通过为该类实现一个反序列化器来做到这一点。

我的问题是 JSON 文件可能格式错误,但raw_json_result仍可以正常解码,但生成的数据结构本身格式错误。在这种情况下,我想返回一个错误。

这里形成有效错误对象的机制是什么?我想我想要一条Err(something_valid)线——我只是不知道如何制作something_valid

impl<'de> Deserialize<'de> for MyClass {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let raw_json_result = MyAliasedClassFromJson::deserialize(deserializer)?;
        MyClass::from_cal_json::<D>(cal_json)
    }
}
Run Code Online (Sandbox Code Playgroud)

Val*_*tin 8

假设您有某种MyError类型,它实现DebugDisplayError。然后,如果您尝试返回Err(MyError::SomethingBadHappened),那么让它工作的最直接方法就是简单地添加.map_err(D::Error::custom).

Err(MyError::SomethingBadHappened).map_err(D::Error::custom)
Run Code Online (Sandbox Code Playgroud)

这是一个简短的例子:

use std::error;
use std::fmt;

// serde = "1.0"
use serde::de::Error;
use serde::{Deserialize, Deserializer};

#[derive(Debug)]
enum MyError {
    YouAreNotBob,
    // ...
}

impl error::Error for MyError {}

impl fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use MyError::*;
        match self {
            YouAreNotBob => write!(f, "YouAreNotBob"),
            // ...
        }
    }
}

pub fn deserialize_bob<'de, D>(deserializer: D) -> Result<String, D::Error>
where
    D: Deserializer<'de>,
{
    let string = String::deserialize(deserializer)?;

    if string == "bob" {
        Ok(string)
    } else {
        Err(MyError::YouAreNotBob).map_err(D::Error::custom)
    }
}
Run Code Online (Sandbox Code Playgroud)