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