#serialization #deserialize #serde #deserialize-json

serde_either

Simple set to enums to deserialize and serialize data that can either be string, struct or vec

4 releases

0.2.1 Aug 13, 2022
0.2.0 May 21, 2021
0.1.1 Apr 17, 2021
0.1.0 Apr 17, 2021

#823 in Data structures

Download history 46/week @ 2023-11-24 36/week @ 2023-12-01 99/week @ 2023-12-08 49/week @ 2023-12-15 74/week @ 2023-12-22 17/week @ 2023-12-29 67/week @ 2024-01-05 52/week @ 2024-01-12 70/week @ 2024-01-19 78/week @ 2024-01-26 40/week @ 2024-02-02 27/week @ 2024-02-09 89/week @ 2024-02-16 79/week @ 2024-02-23 100/week @ 2024-03-01 72/week @ 2024-03-08

347 downloads per month
Used in 4 crates (2 directly)

MIT/Apache

12KB
193 lines

Serde Either

serde_either is a simple library that provides a few enums that enables you to deserialize and serialize values that can have string, struct or vec forms.

Let's say you want to deserialize a json for a Book, and that json has an "authors" field and this files can be either a string or a object like:

{
  "authors": "John Smith"
}

Or like

{
  "authors": {
    "first_name": "John",
    "last_name": "Smith"
  }
}

All you need to do is create a data structure like this:

use serde::{Serialize, Deserialize};
use serde_either::StringOrStruct;
use serde_json;

#[derive(Serialize, Deserialize)]
struct Authors {
  first_name: String,
  last_name: String
}

#[derive(Serialize, Deserialize)]
struct Book {
  pub authors: StringOrStruct<Authors>
}

// And StringOrStruct is just a normal enum

impl Book {
  fn get_author_name(&self) -> String {
    match &self.authors {
      StringOrStruct::String(s) => s.to_owned(),
      StringOrStruct::Struct(author) => format!("{} {}", &author.first_name, &author.last_name)
    }
  }
}

let books = r#"[
    {
        "authors": {
            "first_name": "John",
            "last_name": "Smith"
        }
    },
    {
        "authors": "Michael J. Smith"
    }
]"#;
let res: Vec<Book> = serde_json::from_str(books).unwrap();
assert_eq!(res[0].get_author_name(), "John Smith");
assert_eq!(res[1].get_author_name(), "Michael J. Smith");

And if you need to also capture a possible array of authors like this:

{
  "authors": [
    {
      "first_name": "John",
      "last_name": "Smith"
    },
    {
      "first_name": "Michael",
      "last_name": "Smith"
    },
  ]
}

Then all you need to change is:

use serde_either::StringOrStructOrVec;

// ...

#[derive(Serialize, Deserialize)]
struct Book {
  pub authors: StringOrStructOrVec<Authors, Vec<Authors>>
}

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Dependencies

~340–640KB
~14K SLoC