Есть ли способ заставить serde_ json строго десериализоваться? - PullRequest
2 голосов
/ 02 марта 2020

Что я имею в виду, что если 2 объекта перекрываются по некоторым атрибутам, есть ли способ попытаться сопоставить все из них? Например:

use serde::{Serialize, Deserialize};
use serde_json; // 1.0.47; // 1.0.104

#[derive(Serialize, Deserialize, Debug)]
pub struct A {
    pub item_1: i32,
    pub item_2: i32,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct B {
    pub item_1: i32,
    pub item_2: i32,
    pub item_3: i32,
}

fn main() {
    let json_data = r#"{"item_1" : 10, "item_2" : 100, "item_3" : 1000}"#;
    if let Ok(data) = serde_json::from_str::<A>(json_data) {
        println!("{:?}", data);
    } else if let Ok(data) = serde_json::from_str::<B>(json_data) {
        println!("{:?}", data);
    }
}

Детская площадка

Он всегда выполнялся на A, но я хочу, чтобы он потерпел неудачу, поскольку у него есть дополнительные данные, поэтому он падает до B (где это соответствует точности). Это всего лишь пример проблемы, с которой я столкнулся.

1 Ответ

3 голосов
/ 02 марта 2020

Serde имеет множество атрибутов для настройки этого типа поведения.

Один из них #[serde(deny_unknown_fields)], который делает именно это:

use serde::{Deserialize, Serialize};
use serde_json; // 1.0.47; // 1.0.104

#[derive(Serialize, Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct A {
    pub item_1: i32,
    pub item_2: i32,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct B {
    pub item_1: i32,
    pub item_2: i32,
    pub item_3: i32,
}

fn main() {
    let json_data = r#"{"item_1" : 10, "item_2" : 100, "item_3" : 1000}"#;
    if let Ok(data) = serde_json::from_str::<A>(json_data) {
        println!("{:?}", data);
    } else if let Ok(data) = serde_json::from_str::<B>(json_data) {
        println!("{:?}", data);
    }
}

выходы:

B { item_1: 10, item_2: 100, item_3: 1000 }

( Постоянная ссылка на игровую площадку )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...