3 releases
0.1.2 | Jul 8, 2024 |
---|---|
0.1.1 | Jul 4, 2024 |
0.1.0 | Jul 3, 2024 |
#1746 in Encoding
17KB
228 lines
Serde Duplicate Deserialization Helper Crate
Description
A rust crate with helper macros providing an alternate implementation of serde's Deserialize for cases when duplicate values exist in the source data.
lib.rs
:
Serde Deserialize Duplicates Macros
This crate provides utilities for a very specific purpose: deserializing data with serde with frequent duplicate keys. It provides two helper macros - [DeserializeFirstDuplicate] and [DeserializeLastDuplicate] to allow a selection of order for this end.
Using this crate
Matching Duplicate Names
Take, for example, the following JSON:
{
"myNumber": 34,
"myNumber": 67
}
According to the JSON spec, it is perfectly valid JSON data.
Sometimes we interface with APIs out of our control which can return data like this, and we simply do not care which value we take, only that we have a value and we do not have a runtime panic.
For the following struct, a runtime panic would occur in case the data above was deserialized, due to the duplicate keys.
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct MyStruct {
#[serde(rename = "myNumber")]
my_number: i32
}
Thus, this crate provides alternatives to Deserialize, used as follows:
use serde::Serialize;
use serde_deserialize_duplicates::DeserializeFirstDuplicate;
#[derive(Serialize, DeserializeFirstDuplicate)]
struct MyStruct {
#[serde(rename = "myNumber")]
my_number: i32
}
Now, by replacing Deserialize with this crate's [DeserializeFirstDuplicate], we can simply use the first instance of "my_number" we encounter and ignore the rest. If you are looking for the last value, see [DeserializeLastDuplicate].
Aliased Duplicate Names
This crate also supports deserializing in the case where there is overlapping interpretations of an aliased value.
For example, take this JSON:
{
"breed": "Labarador",
"type": "Labarador"
}
Sometimes we have two fields which exist in JSON that provide identical information and we only want to deserialize one of them in the case we get one.
This can be achieved as follows:
use serde::Serialize;
use serde_deserialize_duplicates::DeserializeLastDuplicate;
#[derive(Serialize, DeserializeLastDuplicate)]
struct Dog {
#[serde(alias = "type")]
breed: String
}
Default fallback values
Occasionally, we may want to load some data which can or cannot exist, and may or may not be a duplicate at the same time.
Serde's default
attribute is supported for this purpose, either deserializing successfully or using a fallback default value.
use serde::Serialize;
use serde_deserialize_duplicates::DeserializeLastDuplicate;
#[derive(Serialize, DeserializeLastDuplicate)]
struct Dog {
#[serde(default)]
occurs_more_than_once: Option<String>
}
Dependencies
~0.3–1MB
~21K SLoC