This crate provides the SingleOrVec
Type which allows
parsing either a single type T or a vector of type T using serde.
This is required when a server either returns an array
if there are multiple values or one value if there is only one.
```rust
struct Response { single: SingleOrVec<'static, u8>, multiple: SingleOrVec<'static, u8>, }
let json = r#"{ "single": 0, "multiple": [ 0, 1, 2 ] }"#; let res: Response = serdejson::fromstr(json).unwrap(); asserteq!(json, &serdejson::tostringpretty(&res).unwrap()); ```
By default the SingleOrVec
Type deserializes its content either
to a single value or an array if it contains multiple values. To change
this behaviour, its possible to define the output format.
```rust
struct Response { single: SingleOrVec<'static, u8>, multiple: SingleOrVec<'static, u8>, }
let json = "[0]";
let res: SingleOrVec<', u8, PreferSingle> = serdejson::fromstr(json).unwrap(); asserteq!("0", &serdejson::tostring(&res).unwrap());
let res: SingleOrVec<', u8, AlwaysVector> = serdejson::fromstr(json).unwrap(); asserteq!("[0]", &serdejson::tostring(&res).unwrap()); ```
The default Backend is a Vec<T>
and thus always results in an allocation.
An alternativ is to use a Cow<'_, T>
as backend which only requires an allocation
for a single value.
Note that this is only valid when using or serializing this value, deserialisation always allocates due to serde#1852
rust
let json = "[0,1,2]";
let res: SingleOrVec<'_, u8, PreferSingle, Cow<'_, [u8]>> = serde_json::from_str(json).unwrap();
assert_eq!(json, &serde_json::to_string(&res).unwrap());
Its also possible to implement Custom Storage Backends by using the Storage
Trait.
```rust use arrayvec::ArrayVec;
struct ArrayVecStorage {}
impl
fn single(ty: T) -> Self::Backing {
let mut vec = ArrayVec::new();
vec.push(ty);
vec
}
fn get_first_with_len(b: &Self::Backing) -> Option<(&T, usize)> {
b.split_first().map(|(t, r)| (t, r.len()))
}
}
let json = "[0,1,2]"; let res: SingleOrVec<', u8, PreferSingle, ArrayVecStorage> = serdejson::fromstr(json).unwrap(); asserteq!(json, &serdejson::tostring(&res).unwrap());
let json = "0"; let res: SingleOrVec<', u8, PreferSingle, ArrayVecStorage> = serdejson::fromstr(json).unwrap(); asserteq!(json, &serdejson::tostring(&res).unwrap()); ```
no_std
It is possible to use this crate with no_std
, however, like serde, either std
or
alloc
is required.
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
License: MIT OR Apache-2.0