Search code examples
jsonrustserdetauri

How to deserialize complex JSON to Rust type?


I am trying to build a Tauri App. I have an error I do not know how to fix, when trying to deserialize data from my frontend to my Rust backend, passed as JSON.

The JSON follows this schema:

{
    positive: ICriterion[],
    negative: ICriterion[],
}

ICriterion {
    name: 'tribunal'|appealCourt'|'group'|'role'|'prevalent_domain'|'placed',
    label: string,
    value: number[]|string|bool
}

We tried implementing the union type for the value field with a Rust Enum:

#[derive(Deserialize)]
pub struct SortDataInput {
    positive: Vec<Criterion>,
    negative: Vec<Criterion>,
}

#[derive(Deserialize)]
pub enum CriterionValue {
    IntegerArray(Vec<i32>),
    Name(String),
    Boolean(bool),
}

#[derive(Deserialize)]
pub struct Criterion {
    name: String,
    value: CriterionValue,
}

But when I try to execute my method, I get an error stating that 'Civil' (which is a possible string value) is an unknown variant.

I guess there is something wrong as to how we set up our Rust enum, but as we are beginners with Rust, we cannot really figure how to fix it.

How would you go about creating the correct type for Serde to easily deserialize our JSON?


Solution

  • By default, enums as serde are [de]serialized with tags, following the format {"Name":"Civil"}.

    What you want is an untagged enum. It serializes the value directly, and deserializes to the first variant that succeeds deserialization:

    #[derive(Deserialize)]
    #[serde(untagged)]
    pub enum CriterionValue {
        IntegerArray(Vec<i32>),
        Name(String),
        Boolean(bool),
    }