Как я могу принять несколько имен десериализации для одного и того же поля Serde? - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь использовать Serde для десериализации файлов JSON (serde-json) и XML (serde-xml-rs) на основе следующей структуры:

use serde_derive::Deserialize;

#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct SchemaConfig {
    pub name: String,
    #[serde(rename = "Cube")]
    pub cubes: Vec<CubeConfig>,
}

Поля, по которым я десериализуюсь, имеют разные имена в зависимости от типа файла. В этом случае я хотел бы, чтобы файл JSON имел ключ cubes со списком кубов, но эквивалент в XML будет состоять из нескольких элементов <Cube />.

Я не могу понять, как принять и cubes, и Cube в качестве ключей для десериализации. Самым близким, что я обнаружил, была опция #[serde(rename = "Cube")], но когда я использую ее, десериализация JSON перестает работать, поскольку она принимает только ключ Cube. Если я уберу эту опцию, десериализация XML перестанет работать, так как она только примет в качестве ключа cubes.

Есть ли простой способ сделать это в Серде?

1 Ответ

0 голосов
/ 30 марта 2019

Я рекомендую вам прочитать документацию Serde. В поле атрибуты поля вводится атрибут alias , выделение:

#[serde(alias = "name")]

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

use serde::Deserialize; // 1.0.88
use serde_json; // 1.0.38

#[derive(Debug, Deserialize)]
struct SchemaConfig {
    #[serde(alias = "fancy_square", alias = "KUBE")]
    cube: [i32; 3],
}

fn main() -> Result<(), Box<std::error::Error>> {
    let input1 = r#"{
        "fancy_square": [1, 2, 3]
    }"#;

    let input2 = r#"{
        "KUBE": [4, 5, 6]
    }"#;

    let one: SchemaConfig = serde_json::from_str(input1)?;
    let two: SchemaConfig = serde_json::from_str(input2)?;

    println!("{:?}", one);
    println!("{:?}", two);

    Ok(())
}

Я бы хотел, чтобы файл JSON имел ключ cubes со списком кубов, но эквивалент в XML будет состоять из нескольких элементов <Cube />.

Это, безусловно, звучит так, как будто вы хотите две разные структуры для ваших файлов. В этом случае посмотрите на что-то вроде:

...