77//!
88//! With `N = 1`, no heap allocation is needed when a single variant is present — the common case.
99//!
10+ //! # Format selection
11+ //! When the serializer/deserializer is **human-readable** (e.g. JSON), the map-with-string-keys
12+ //! format is used. For **binary** formats (e.g. postcard), a plain sequence is used instead:
13+ //! each element is serialized using serde's standard externally-tagged enum representation
14+ //! (`u32` variant index + value), which avoids all string allocations and is more compact.
15+ //!
1016//! # Constraints
1117//! `V` must be an enum where every active variant is a newtype variant (single unnamed field).
1218//! Unit, tuple, and struct variants are not supported and will return a serde error at runtime.
@@ -17,8 +23,8 @@ use serde::{
1723 Deserializer ,
1824 Serialize ,
1925 Serializer ,
20- de:: { MapAccess , Visitor } ,
21- ser:: SerializeMap ,
26+ de:: { MapAccess , SeqAccess , Visitor } ,
27+ ser:: { SerializeMap , SerializeSeq } ,
2228} ;
2329use smallvec:: SmallVec ;
2430use std:: ops:: { Deref , DerefMut } ;
@@ -116,14 +122,25 @@ where
116122 where
117123 S : Serializer ,
118124 {
119- let mut map = serializer. serialize_map ( Some ( self . 0 . len ( ) ) ) ?;
120- for v in & self . 0 {
121- // Route each element through MapEntrySerializer, which intercepts the
122- // serialize_newtype_variant call that serde generates for enum variants
123- // and writes it directly as a map key-value pair.
124- v. serialize ( MapEntrySerializer { map : & mut map } ) ?;
125+ if serializer. is_human_readable ( ) {
126+ // Human-readable (e.g. JSON): map with string variant-name keys.
127+ let mut map = serializer. serialize_map ( Some ( self . 0 . len ( ) ) ) ?;
128+ for v in & self . 0 {
129+ // Route each element through MapEntrySerializer, which intercepts the
130+ // serialize_newtype_variant call that serde generates for enum variants
131+ // and writes it directly as a map key-value pair.
132+ v. serialize ( MapEntrySerializer { map : & mut map } ) ?;
133+ }
134+ map. end ( )
135+ } else {
136+ // Binary (e.g. postcard): plain sequence of externally-tagged enum values.
137+ // Each element is encoded as (u32 variant_index, payload) — no string keys.
138+ let mut seq = serializer. serialize_seq ( Some ( self . 0 . len ( ) ) ) ?;
139+ for v in & self . 0 {
140+ seq. serialize_element ( v) ?;
141+ }
142+ seq. end ( )
125143 }
126- map. end ( )
127144 }
128145}
129146
@@ -275,9 +292,9 @@ where
275292 where
276293 D : Deserializer < ' de > ,
277294 {
278- struct SmallVecEnumMapVisitor < V , const N : usize > ( std:: marker:: PhantomData < [ V ; N ] > ) ;
295+ struct SmallVecEnumMapMapVisitor < V , const N : usize > ( std:: marker:: PhantomData < [ V ; N ] > ) ;
279296
280- impl < ' de , V , const N : usize > Visitor < ' de > for SmallVecEnumMapVisitor < V , N >
297+ impl < ' de , V , const N : usize > Visitor < ' de > for SmallVecEnumMapMapVisitor < V , N >
281298 where
282299 V : Deserialize < ' de > ,
283300 {
@@ -303,7 +320,35 @@ where
303320 }
304321 }
305322
306- deserializer. deserialize_map ( SmallVecEnumMapVisitor ( std:: marker:: PhantomData ) )
323+ struct SmallVecEnumMapSeqVisitor < V , const N : usize > ( std:: marker:: PhantomData < [ V ; N ] > ) ;
324+
325+ impl < ' de , V , const N : usize > Visitor < ' de > for SmallVecEnumMapSeqVisitor < V , N >
326+ where
327+ V : Deserialize < ' de > ,
328+ {
329+ type Value = SmallVecEnumMap < V , N > ;
330+
331+ fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
332+ formatter. write_str ( "a sequence that can be converted into a SmallVecEnumMap" )
333+ }
334+
335+ fn visit_seq < A > ( self , mut seq : A ) -> Result < Self :: Value , A :: Error >
336+ where
337+ A : SeqAccess < ' de > ,
338+ {
339+ let mut smallvec = SmallVec :: new ( ) ;
340+ while let Some ( v) = seq. next_element :: < V > ( ) ? {
341+ smallvec. push ( v) ;
342+ }
343+ Ok ( SmallVecEnumMap ( smallvec) )
344+ }
345+ }
346+
347+ if deserializer. is_human_readable ( ) {
348+ deserializer. deserialize_map ( SmallVecEnumMapMapVisitor ( std:: marker:: PhantomData ) )
349+ } else {
350+ deserializer. deserialize_seq ( SmallVecEnumMapSeqVisitor ( std:: marker:: PhantomData ) )
351+ }
307352 }
308353}
309354
0 commit comments