| 1 | //! Functions to serialize and deserialize an [`IndexMap`] as an ordered sequence. |
| 2 | //! |
| 3 | //! The default `serde` implementation serializes `IndexMap` as a normal map, |
| 4 | //! but there is no guarantee that serialization formats will preserve the order |
| 5 | //! of the key-value pairs. This module serializes `IndexMap` as a sequence of |
| 6 | //! `(key, value)` elements instead, in order. |
| 7 | //! |
| 8 | //! This module may be used in a field attribute for derived implementations: |
| 9 | //! |
| 10 | //! ``` |
| 11 | //! # use indexmap::IndexMap; |
| 12 | //! # use serde_derive::{Deserialize, Serialize}; |
| 13 | //! #[derive(Deserialize, Serialize)] |
| 14 | //! struct Data { |
| 15 | //! #[serde(with = "indexmap::map::serde_seq" )] |
| 16 | //! map: IndexMap<i32, u64>, |
| 17 | //! // ... |
| 18 | //! } |
| 19 | //! ``` |
| 20 | |
| 21 | use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor}; |
| 22 | use serde::ser::{Serialize, Serializer}; |
| 23 | |
| 24 | use core::fmt::{self, Formatter}; |
| 25 | use core::hash::{BuildHasher, Hash}; |
| 26 | use core::marker::PhantomData; |
| 27 | |
| 28 | use crate::map::Slice as MapSlice; |
| 29 | use crate::serde::cautious_capacity; |
| 30 | use crate::set::Slice as SetSlice; |
| 31 | use crate::IndexMap; |
| 32 | |
| 33 | /// Serializes a [`map::Slice`][MapSlice] as an ordered sequence. |
| 34 | /// |
| 35 | /// This behaves like [`crate::map::serde_seq`] for `IndexMap`, serializing a sequence |
| 36 | /// of `(key, value)` pairs, rather than as a map that might not preserve order. |
| 37 | impl<K, V> Serialize for MapSlice<K, V> |
| 38 | where |
| 39 | K: Serialize, |
| 40 | V: Serialize, |
| 41 | { |
| 42 | fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error> |
| 43 | where |
| 44 | T: Serializer, |
| 45 | { |
| 46 | serializer.collect_seq(self) |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | /// Serializes a [`set::Slice`][SetSlice] as an ordered sequence. |
| 51 | impl<T> Serialize for SetSlice<T> |
| 52 | where |
| 53 | T: Serialize, |
| 54 | { |
| 55 | fn serialize<Se>(&self, serializer: Se) -> Result<Se::Ok, Se::Error> |
| 56 | where |
| 57 | Se: Serializer, |
| 58 | { |
| 59 | serializer.collect_seq(self) |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | /// Serializes an [`IndexMap`] as an ordered sequence. |
| 64 | /// |
| 65 | /// This function may be used in a field attribute for deriving [`Serialize`]: |
| 66 | /// |
| 67 | /// ``` |
| 68 | /// # use indexmap::IndexMap; |
| 69 | /// # use serde_derive::Serialize; |
| 70 | /// #[derive(Serialize)] |
| 71 | /// struct Data { |
| 72 | /// #[serde(serialize_with = "indexmap::map::serde_seq::serialize" )] |
| 73 | /// map: IndexMap<i32, u64>, |
| 74 | /// // ... |
| 75 | /// } |
| 76 | /// ``` |
| 77 | pub fn serialize<K, V, S, T>(map: &IndexMap<K, V, S>, serializer: T) -> Result<T::Ok, T::Error> |
| 78 | where |
| 79 | K: Serialize, |
| 80 | V: Serialize, |
| 81 | T: Serializer, |
| 82 | { |
| 83 | serializer.collect_seq(iter:map) |
| 84 | } |
| 85 | |
| 86 | /// Visitor to deserialize a *sequenced* `IndexMap` |
| 87 | struct SeqVisitor<K, V, S>(PhantomData<(K, V, S)>); |
| 88 | |
| 89 | impl<'de, K, V, S> Visitor<'de> for SeqVisitor<K, V, S> |
| 90 | where |
| 91 | K: Deserialize<'de> + Eq + Hash, |
| 92 | V: Deserialize<'de>, |
| 93 | S: Default + BuildHasher, |
| 94 | { |
| 95 | type Value = IndexMap<K, V, S>; |
| 96 | |
| 97 | fn expecting(&self, formatter: &mut Formatter<'_>) -> fmt::Result { |
| 98 | write!(formatter, "a sequenced map" ) |
| 99 | } |
| 100 | |
| 101 | fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> |
| 102 | where |
| 103 | A: SeqAccess<'de>, |
| 104 | { |
| 105 | let capacity: usize = cautious_capacity::<K, V>(seq.size_hint()); |
| 106 | let mut map: IndexMap = IndexMap::with_capacity_and_hasher(n:capacity, S::default()); |
| 107 | |
| 108 | while let Some((key: K, value: V)) = seq.next_element()? { |
| 109 | map.insert(key, value); |
| 110 | } |
| 111 | |
| 112 | Ok(map) |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | /// Deserializes an [`IndexMap`] from an ordered sequence. |
| 117 | /// |
| 118 | /// This function may be used in a field attribute for deriving [`Deserialize`]: |
| 119 | /// |
| 120 | /// ``` |
| 121 | /// # use indexmap::IndexMap; |
| 122 | /// # use serde_derive::Deserialize; |
| 123 | /// #[derive(Deserialize)] |
| 124 | /// struct Data { |
| 125 | /// #[serde(deserialize_with = "indexmap::map::serde_seq::deserialize" )] |
| 126 | /// map: IndexMap<i32, u64>, |
| 127 | /// // ... |
| 128 | /// } |
| 129 | /// ``` |
| 130 | pub fn deserialize<'de, D, K, V, S>(deserializer: D) -> Result<IndexMap<K, V, S>, D::Error> |
| 131 | where |
| 132 | D: Deserializer<'de>, |
| 133 | K: Deserialize<'de> + Eq + Hash, |
| 134 | V: Deserialize<'de>, |
| 135 | S: Default + BuildHasher, |
| 136 | { |
| 137 | deserializer.deserialize_seq(visitor:SeqVisitor(PhantomData)) |
| 138 | } |
| 139 | |