[−][src]Crate serde_single_or_vec
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.
Example
#[derive(Deserialize, Serialize)] struct Response { single: SingleOrVec<'static, u8>, multiple: SingleOrVec<'static, u8>, } let json = r#"{ "single": 0, "multiple": [ 0, 1, 2 ] }"#; let res: Response = serde_json::from_str(json).unwrap(); assert_eq!(json, &serde_json::to_string_pretty(&res).unwrap());
Format
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.
#[derive(Deserialize, Serialize)] struct Response { single: SingleOrVec<'static, u8>, multiple: SingleOrVec<'static, u8>, } let json = "[0]"; let res: SingleOrVec<'_, u8, PreferSingle> = serde_json::from_str(json).unwrap(); assert_eq!("0", &serde_json::to_string(&res).unwrap()); let res: SingleOrVec<'_, u8, AlwaysVector> = serde_json::from_str(json).unwrap(); assert_eq!("[0]", &serde_json::to_string(&res).unwrap());
Storage Backend
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
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());
Custom Storage Type
Its also possible to implement Custom Storage Backends by using the Storage
Trait.
use arrayvec::ArrayVec; struct ArrayVecStorage {} impl<T> Storage<'_, T> for ArrayVecStorage { type Backing = ArrayVec<[T; 4]>; 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> = serde_json::from_str(json).unwrap(); assert_eq!(json, &serde_json::to_string(&res).unwrap()); let json = "0"; let res: SingleOrVec<'_, u8, PreferSingle, ArrayVecStorage> = serde_json::from_str(json).unwrap(); assert_eq!(json, &serde_json::to_string(&res).unwrap());
no_std
It is possible to use this crate with no_std
, however, like serde, either std
or
alloc
is required.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
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.
Structs
AlwaysVector | Always returns a vector on serialisation |
PreferSingle | Returns a single value on serialisation if there is only one in the vector |
SingleOrVec | Provides a type which can be used to parse server respsonses which either return an array or only a single value. |
Traits
Format | Specifies whether Serializsation should fall back to a single value or not |
Storage | Specifies the internal Storage Type of the Sequence |