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::set::Slice as SetSlice; |
30 | use crate::IndexMap; |
31 | |
32 | /// Serializes a `map::Slice` as an ordered sequence. |
33 | /// |
34 | /// This behaves like [`crate::map::serde_seq`] for `IndexMap`, serializing a sequence |
35 | /// of `(key, value)` pairs, rather than as a map that might not preserve order. |
36 | impl<K, V> Serialize for MapSlice<K, V> |
37 | where |
38 | K: Serialize, |
39 | V: Serialize, |
40 | { |
41 | fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error> |
42 | where |
43 | T: Serializer, |
44 | { |
45 | serializer.collect_seq(self) |
46 | } |
47 | } |
48 | |
49 | /// Serializes a `set::Slice` as an ordered sequence. |
50 | impl<T> Serialize for SetSlice<T> |
51 | where |
52 | T: Serialize, |
53 | { |
54 | fn serialize<Se>(&self, serializer: Se) -> Result<Se::Ok, Se::Error> |
55 | where |
56 | Se: Serializer, |
57 | { |
58 | serializer.collect_seq(self) |
59 | } |
60 | } |
61 | |
62 | /// Serializes an `IndexMap` as an ordered sequence. |
63 | /// |
64 | /// This function may be used in a field attribute for deriving `Serialize`: |
65 | /// |
66 | /// ``` |
67 | /// # use indexmap::IndexMap; |
68 | /// # use serde_derive::Serialize; |
69 | /// #[derive(Serialize)] |
70 | /// struct Data { |
71 | /// #[serde(serialize_with = "indexmap::map::serde_seq::serialize" )] |
72 | /// map: IndexMap<i32, u64>, |
73 | /// // ... |
74 | /// } |
75 | /// ``` |
76 | pub fn serialize<K, V, S, T>(map: &IndexMap<K, V, S>, serializer: T) -> Result<T::Ok, T::Error> |
77 | where |
78 | K: Serialize + Hash + Eq, |
79 | V: Serialize, |
80 | S: BuildHasher, |
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 = seq.size_hint().unwrap_or(default:0); |
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 | |