Struct serde_with::KeyValueMap

source ·
pub struct KeyValueMap<T>(/* private fields */);
Expand description

Convert Vec elements into key-value map entries

This maps a single struct/tuple/etc. to a map entry. The map key is converted to a struct field. The other values will be mapped to the map value.

The conversion supports structs, tuple structs, tuples, maps, and sequences. Structs need a field that is named $key$ to be used as the map key. This can be done with the #[serde(rename = "$key$")] attribute. Maps similarly need a map-key that is named $key$. For tuples, tuple structs, and sequences the first element is used as the map key.

Examples

Struct with String key in JSON

use serde_with::{serde_as, KeyValueMap};

#[derive(Serialize, Deserialize)]
struct SimpleStruct {
    b: bool,
    // The field named `$key$` will become the map key
    #[serde(rename = "$key$")]
    id: String,
    i: i32,
}

#[serde_as]
#[derive(Serialize, Deserialize)]
struct KVMap(
    #[serde_as(as = "KeyValueMap<_>")]
    Vec<SimpleStruct>,
);

// ---

// This will serialize this list of values
let values = KVMap(vec![
    SimpleStruct {
        b: false,
        id: "id-0000".to_string(),
        i: 123,
    },
    SimpleStruct {
        b: true,
        id: "id-0001".to_string(),
        i: 555,
    },
    SimpleStruct {
        b: false,
        id: "id-0002".to_string(),
        i: 987,
    },
]);

// into this JSON map
let expected =
r#"{
  "id-0000": {
    "b": false,
    "i": 123
  },
  "id-0001": {
    "b": true,
    "i": 555
  },
  "id-0002": {
    "b": false,
    "i": 987
  }
}"#;

// Both serialization and deserialization work flawlessly.
let serialized = serde_json::to_string_pretty(&values).unwrap();
assert_eq!(expected, serialized);
let deserialized: KVMap = serde_json::from_str(&serialized).unwrap();
assert_eq!(values, deserialized);

Tuple struct with complex key in YAML

use serde_with::{serde_as, KeyValueMap};
use std::net::IpAddr;

#[derive(Serialize, Deserialize)]
struct TupleStruct (
    // The first element in a tuple struct, tuple, or sequence becomes the map key
    (IpAddr, u8),
    bool,
);

#[serde_as]
#[derive(Serialize, Deserialize)]
struct KVMap(
    #[serde_as(as = "KeyValueMap<_>")]
    Vec<TupleStruct>,
);

// ---

// This will serialize this list of values
let values = KVMap(vec![
    TupleStruct(
        (IpAddr::from_str("127.0.0.1").unwrap(), 8),
        true
    ),
    TupleStruct(
        (IpAddr::from_str("::1").unwrap(), 128),
        true
    ),
    TupleStruct(
        (IpAddr::from_str("198.51.100.0").unwrap(), 24),
        true
    ),
]);

// into this YAML
let expected =
r#"? - 127.0.0.1
  - 8
: - true
? - ::1
  - 128
: - true
? - 198.51.100.0
  - 24
: - true
"#;

// Both serialization and deserialization work flawlessly.
let serialized = serde_yaml::to_string(&values).unwrap();
assert_eq!(expected, serialized);
let deserialized: KVMap = serde_yaml::from_str(&serialized).unwrap();
assert_eq!(values, deserialized);

Trait Implementations§

source§

impl<'de, T, TAs> DeserializeAs<'de, Vec<T>> for KeyValueMap<TAs>
where TAs: DeserializeAs<'de, T>,

source§

fn deserialize_as<D>(deserializer: D) -> Result<Vec<T>, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer.
source§

impl<T, TAs> SerializeAs<Vec<T>> for KeyValueMap<TAs>
where TAs: SerializeAs<T>,

source§

fn serialize_as<S>(source: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer.

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for KeyValueMap<T>
where T: RefUnwindSafe,

§

impl<T> Send for KeyValueMap<T>
where T: Send,

§

impl<T> Sync for KeyValueMap<T>
where T: Sync,

§

impl<T> Unpin for KeyValueMap<T>
where T: Unpin,

§

impl<T> UnwindSafe for KeyValueMap<T>
where T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.