如何知道未给定的字段值具有默认值

How to know a field value not given which has a default value

提问人:firefantasy 提问时间:10/26/2023 最后编辑:cafce25firefantasy 更新时间:10/26/2023 访问量:43

问:

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);
}

操场

示例打印 ,因为没有给出字段,有没有办法知道它在 var 中没有给出?Timeout(30)timeoutrequest

评论

2赞 cafce25 10/26/2023
如果你像这样建模,你就不能这样做,我认为要做到这一点,就必须没有注释。timeoutOption<Timeout>#[serde(default)]

答:

0赞 Chayim Friedman 10/26/2023 #1

如果你真的想要它:

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());
}

游乐场

但是,最好只是反序列化 .Option