serde_single_or_vec 1.0.0

Type which can be deserialized from either a sequence or a single value
Documentation
# 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

```rust

#[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.

```rust

#[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](https://github.com/serde-rs/serde/issues/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());
```

## Custom Storage Type

Its also possible to implement Custom Storage Backends by using the `Storage` Trait.

```rust
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]LICENSE-APACHE or [http://www.apache.org/licenses/LICENSE-2.0]http://www.apache.org/licenses/LICENSE-2.0)
* MIT license
  ([LICENSE-MIT]LICENSE-MIT or [http://opensource.org/licenses/MIT]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.


License: MIT OR Apache-2.0