rust 如何知道一个没有给出的字段值有一个默认值

ee7vknir  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(99)
use serde::Deserialize;

#[derive(Deserialize, Debug)]
struct Request {
    #[serde(default)]
    timeout: Timeout,
}

/// Timeout in seconds.
#[derive(Deserialize, Debug)]
struct Timeout(u32);
impl Default for Timeout {
    fn default() -> Self {
        Timeout(30)
    }
}

fn main() {
    let json = r#"{}"#;
    let request: Request = serde_json::from_str(json).unwrap();
    println!("{:?}", request.timeout);
}

字符串
Playground
这个例子打印了Timeout(30),因为没有给出timeout字段,有没有办法知道它没有在request变量中给出?

mzillmmw

mzillmmw1#

如果你真的想要它:

use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct DefaultTracked<T> {
    pub value: T,
    #[serde(skip)]
    default_initialized: bool,
}

impl<T: Default> Default for DefaultTracked<T> {
    fn default() -> Self {
        Self {
            value: T::default(),
            default_initialized: true,
        }
    }
}

impl<T> DefaultTracked<T> {
    pub fn new(value: T) -> Self {
        Self {
            value,
            default_initialized: false,
        }
    }
    
    pub fn default_initialized(&self) -> bool {
        self.default_initialized
    }
}

#[derive(Deserialize, Debug)]
struct Request {
    #[serde(default)]
    timeout: DefaultTracked<Timeout>,
}

/// Timeout in seconds.
#[derive(Deserialize, Debug)]
struct Timeout(u32);
impl Default for Timeout {
    fn default() -> Self {
        Timeout(30)
    }
}

fn main() {
    let json = r#"{}"#;
    let request: Request = serde_json::from_str(json).unwrap();
    assert_eq!(request.timeout.value.0, 30);
    assert!(request.timeout.default_initialized());
    
    let json = r#"{"timeout":30}"#;
    let request: Request = serde_json::from_str(json).unwrap();
    assert_eq!(request.timeout.value.0, 30);
    assert!(!request.timeout.default_initialized());
}

字符串
Playground的一个。
但是,最好只对Option进行反序列化。

相关问题