Как я могу принять несколько имен десериализации для одного и того же поля Serde?

Я пытаюсь использовать 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 в качестве ключа.

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


person MarcioPorto    schedule 11.01.2019    source источник


Ответы (1)


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

#[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 />.

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

person Shepmaster    schedule 30.03.2019
comment
Спасибо за образец кода. Я прочитал документацию, но из документации мне было непонятно, как указать несколько значений alias. Ваш пример кода здесь делает это совершенно ясным. ???? - person Gary Sheppard; 29.01.2020