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 | |