serde-rs / json

Strongly typed JSON library for Rust
Apache License 2.0
4.7k stars 536 forks source link

not ignoring unknow field by default and how do i make this work? #1145

Closed ogios closed 3 weeks ago

ogios commented 3 weeks ago

i saw that the doc says it will ignore unknow fields by default if you don't specify deny_unknown_fields, but it still raises error:

thread 'main' panicked at src/main.rs:73:48:
called `Result::unwrap()` on an `Err` value: Error("invalid type: string \"$schema\", expected struct Temp", line: 2, column: 17)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
fn main() {
    parse_config_test()
}

use serde::Deserialize;
#[derive(Deserialize, Debug, Default)]
#[serde(default)]
pub struct RawConfig {
    #[serde(default = "dt_edge")]
    pub edge: String,
    #[serde(default)]
    pub position: String,
    #[serde(default = "dt_width")]
    pub width: f64,
    #[serde(default)]
    pub height: f64,
    #[serde(default = "dt_rel_height")]
    pub rel_height: f64,
    #[serde(default)]
    pub event_map: Vec<(u32, String)>,
    #[serde(default = "dt_color")]
    pub color: String,
    #[serde(default = "dt_duration")]
    pub transition_duration: u32,
    #[serde(default = "dt_frame_rate")]
    pub frame_rate: u32,
    #[serde(default = "dt_trigger_size")]
    pub extra_trigger_size: f64,
}
fn dt_edge() -> String {
    String::from("left")
}
fn dt_width() -> f64 {
    15.
}
fn dt_rel_height() -> f64 {
    0.3
}
fn dt_color() -> String {
    String::from("#7B98FF")
}
fn dt_duration() -> u32 {
    300
}
fn dt_frame_rate() -> u32 {
    30
}
fn dt_trigger_size() -> f64 {
    5.
}

#[derive(Deserialize, Debug)]
struct Temp {
    #[serde(default)]
    widgets: Vec<RawConfig>,
}

pub fn parse_config_test() {
    // ignore `$schema`, i know that the doc says it will ignore unknown field by default but it's not working.
    // and also `RawConfig` inside `widgets` will fail to deserialize but i've set default feilds and functions already, is there something missing?
    let data = r#"
        "$schema": "sfa"
        "widgets": [
            {
                "edge": "top",
                "position": "left",
                "width": 20,
                "rel_height": 0.5
            }
        ],
        "#;

    let res: Temp = serde_json::from_str(data).unwrap();
    println!("res: {:#?}", res);
}

cargo toml dependency:

serde_json = "1.0.117"
serde = { version = "1.0.203", features = ["derive"] }
ogios commented 3 weeks ago

really sorry, i didn't add the surrounding.