1use super::codec::{
19 field_ref_mode, field_type_with_ref_flags, generic_field_type, Codec, CodecReadType,
20};
21use super::collection::check_count_write_bytes;
22use crate::context::{ReadContext, WriteContext};
23use crate::error::Error;
24use crate::meta::FieldType;
25use crate::resolver::{RefFlag, RefMode, TypeInfo, TypeResolver};
26use crate::serializer::{core::read_value_type_info, Serializer};
27use crate::type_id::{need_to_write_type_for_field, TypeId, SIZE_OF_REF_AND_TYPE};
28use std::borrow::Cow;
29use std::collections::{BTreeMap, HashMap};
30use std::marker::PhantomData;
31use std::rc::Rc;
32
33const MAX_CHUNK_SIZE: u8 = 255;
34pub(crate) const TRACKING_KEY_REF: u8 = 0b1;
35pub(crate) const KEY_NULL: u8 = 0b10;
36pub(crate) const DECL_KEY_TYPE: u8 = 0b100;
37pub(crate) const TRACKING_VALUE_REF: u8 = 0b1000;
38pub(crate) const VALUE_NULL: u8 = 0b10000;
39pub(crate) const DECL_VALUE_TYPE: u8 = 0b100000;
40
41pub struct BTreeMapCodec<K, V, KC, VC, const NULLABLE: bool, const TRACK_REF: bool>(
42 PhantomData<(K, V, KC, VC)>,
43);
44
45pub struct HashMapCodec<K, V, KC, VC, const NULLABLE: bool, const TRACK_REF: bool>(
46 PhantomData<(K, V, KC, VC)>,
47);
48
49trait MapTarget<K, V>: Sized {
50 fn with_capacity(capacity: usize) -> Self;
51 fn insert(&mut self, key: K, value: V);
52}
53
54impl<K: Eq + std::hash::Hash, V> MapTarget<K, V> for HashMap<K, V> {
55 #[inline(always)]
56 fn with_capacity(capacity: usize) -> Self {
57 HashMap::with_capacity(capacity)
58 }
59
60 #[inline(always)]
61 fn insert(&mut self, key: K, value: V) {
62 HashMap::insert(self, key, value);
63 }
64}
65
66impl<K: Ord, V> MapTarget<K, V> for BTreeMap<K, V> {
67 #[inline(always)]
68 fn with_capacity(_: usize) -> Self {
69 BTreeMap::new()
70 }
71
72 #[inline(always)]
73 fn insert(&mut self, key: K, value: V) {
74 BTreeMap::insert(self, key, value);
75 }
76}
77
78#[inline(always)]
79fn write_entry_type<T: 'static, S: Serializer<Target = T>>(
80 context: &mut WriteContext,
81 target_type_id: Option<std::any::TypeId>,
82) -> Result<Option<Rc<TypeInfo>>, Error> {
83 if let Some(target_type_id) = target_type_id {
84 S::write_type_info_value(context, target_type_id).map(Some)
85 } else {
86 S::write_type_info(context)?;
87 Ok(None)
88 }
89}
90
91macro_rules! map_write_mode {
92 (value, $T:ty, $S:ty, $value:expr, $context:expr, $ref_mode:expr, $write_type:expr, $has_generics:expr) => {
93 <$S as Serializer>::write($value, $context, $ref_mode, $write_type)
94 };
95 (field, $T:ty, $C:ty, $value:expr, $context:expr, $ref_mode:expr, $write_type:expr, $has_generics:expr) => {
96 <$C as Codec<$T>>::write_with_mode($value, $context, $ref_mode, $write_type, $has_generics)
97 };
98}
99
100macro_rules! map_write_with_info {
101 (value, $T:ty, $S:ty, $value:expr, $context:expr, $ref_mode:expr, $type_info:expr, $has_generics:expr) => {
102 <$S as Serializer>::write_with_type_info($value, $context, $ref_mode, $type_info)
103 };
104 (field, $T:ty, $C:ty, $value:expr, $context:expr, $ref_mode:expr, $type_info:expr, $has_generics:expr) => {
105 <$C as Codec<$T>>::write_with_type_info(
106 $value,
107 $context,
108 $ref_mode,
109 $type_info,
110 $has_generics,
111 )
112 };
113}
114
115macro_rules! map_write_entry {
116 ($layer:ident, $T:ty, $C:ty, $value:expr, $context:expr, $track_ref:expr, $has_generics:expr, $type_info:expr) => {{
117 let ref_mode = if $track_ref {
118 RefMode::Tracking
119 } else {
120 RefMode::None
121 };
122 if let Some(type_info) = $type_info {
123 map_write_with_info!(
124 $layer,
125 $T,
126 $C,
127 $value,
128 $context,
129 ref_mode,
130 type_info,
131 $has_generics
132 )
133 } else {
134 map_write_mode!(
135 $layer,
136 $T,
137 $C,
138 $value,
139 $context,
140 ref_mode,
141 false,
142 $has_generics
143 )
144 }
145 }};
146}
147
148macro_rules! map_reserved_space {
149 (value, $T:ty, $S:ty) => {
150 <$S as Serializer>::reserved_space()
151 };
152 (field, $T:ty, $C:ty) => {
153 <$C as Codec<$T>>::field_reserved_space()
154 };
155}
156
157macro_rules! write_map_data_body {
158 (
159 $layer:ident,
160 $K:ident,
161 $V:ident,
162 $KC:ident,
163 $VC:ident,
164 $iter:expr,
165 $len:expr,
166 $context:expr,
167 $has_generics:expr
168 ) => {{
169 let context = $context;
170 let len = $len;
171 context.writer.write_var_u32(len as u32);
172 if len == 0 {
173 return Ok(());
174 }
175 let body_offset = context.writer.len();
176 context.writer.reserve(
177 len.saturating_mul(
178 map_reserved_space!($layer, $K, $KC)
179 .saturating_add(map_reserved_space!($layer, $V, $VC)),
180 ),
181 );
182
183 let has_generics = $has_generics;
184 let key_declared = has_generics && !need_to_write_type_for_field($KC::static_type_id());
185 let value_declared = has_generics && !need_to_write_type_for_field($VC::static_type_id());
186 let key_polymorphic = $KC::IS_POLYMORPHIC;
187 let value_polymorphic = $VC::IS_POLYMORPHIC;
188 let key_shared = $KC::IS_SHARED_REF;
189 let value_shared = $VC::IS_SHARED_REF;
190 let mut key_type = None;
191 let mut value_type = None;
192 let mut key_info = None;
193 let mut value_info = None;
194 let mut header_offset = 0;
195 let mut pair_count = 0u8;
196 let mut need_header = true;
197
198 for (key, value) in $iter {
199 let next_key_type = if key_polymorphic {
204 $KC::dynamic_type_id(key)?
205 } else {
206 None
207 };
208 let next_value_type = if value_polymorphic {
209 $VC::dynamic_type_id(value)?
210 } else {
211 None
212 };
213 let key_none = if key_polymorphic {
214 next_key_type.is_none()
215 } else {
216 $KC::is_none(key)
217 };
218 let value_none = if value_polymorphic {
219 next_value_type.is_none()
220 } else {
221 $VC::is_none(value)
222 };
223 if key_none || value_none {
224 if pair_count != 0 {
225 context.writer.set_bytes(header_offset + 1, &[pair_count]);
226 pair_count = 0;
227 need_header = true;
228 }
229 if key_none && value_none {
230 context.writer.write_u8(KEY_NULL | VALUE_NULL);
231 continue;
232 }
233 if value_none {
234 let mut header = VALUE_NULL;
235 if key_shared {
236 header |= TRACKING_KEY_REF;
237 }
238 if key_declared && !key_polymorphic {
239 header |= DECL_KEY_TYPE;
240 context.writer.write_u8(header);
241 map_write_entry!(
242 $layer,
243 $K,
244 $KC,
245 key,
246 context,
247 key_shared,
248 has_generics,
249 None
250 )?;
251 } else {
252 context.writer.write_u8(header);
253 if key_shared {
254 map_write_mode!(
255 $layer,
256 $K,
257 $KC,
258 key,
259 context,
260 RefMode::Tracking,
261 true,
262 has_generics
263 )?;
264 } else {
265 let key_info = write_entry_type::<$K, $KC>(context, next_key_type)?;
266 map_write_entry!(
267 $layer,
268 $K,
269 $KC,
270 key,
271 context,
272 false,
273 has_generics,
274 key_info.as_ref()
275 )?;
276 }
277 }
278 continue;
279 }
280 let mut header = KEY_NULL;
281 if value_shared {
282 header |= TRACKING_VALUE_REF;
283 }
284 if value_declared && !value_polymorphic {
285 header |= DECL_VALUE_TYPE;
286 context.writer.write_u8(header);
287 map_write_entry!(
288 $layer,
289 $V,
290 $VC,
291 value,
292 context,
293 value_shared,
294 has_generics,
295 None
296 )?;
297 } else {
298 context.writer.write_u8(header);
299 if value_shared {
300 map_write_mode!(
301 $layer,
302 $V,
303 $VC,
304 value,
305 context,
306 RefMode::Tracking,
307 true,
308 has_generics
309 )?;
310 } else {
311 let value_info = write_entry_type::<$V, $VC>(context, next_value_type)?;
312 map_write_entry!(
313 $layer,
314 $V,
315 $VC,
316 value,
317 context,
318 false,
319 has_generics,
320 value_info.as_ref()
321 )?;
322 }
323 }
324 continue;
325 }
326
327 let types_changed = (key_polymorphic || value_polymorphic)
328 && (next_key_type != key_type || next_value_type != value_type);
329 if need_header || types_changed {
330 if pair_count != 0 {
331 context.writer.set_bytes(header_offset + 1, &[pair_count]);
332 pair_count = 0;
333 }
334 header_offset = context.writer.len();
335 context.writer.write_i16(-1);
336 let mut header = 0;
337 if key_shared {
338 header |= TRACKING_KEY_REF;
339 }
340 if value_shared {
341 header |= TRACKING_VALUE_REF;
342 }
343 if key_declared && !key_polymorphic {
344 header |= DECL_KEY_TYPE;
345 key_info = None;
346 } else {
347 key_info = write_entry_type::<$K, $KC>(context, next_key_type)?;
348 }
349 if value_declared && !value_polymorphic {
350 header |= DECL_VALUE_TYPE;
351 value_info = None;
352 } else {
353 value_info = write_entry_type::<$V, $VC>(context, next_value_type)?;
354 }
355 context.writer.set_bytes(header_offset, &[header]);
356 need_header = false;
357 key_type = next_key_type;
358 value_type = next_value_type;
359 }
360
361 map_write_entry!(
362 $layer,
363 $K,
364 $KC,
365 key,
366 context,
367 key_shared,
368 has_generics,
369 key_info.as_ref()
370 )?;
371 map_write_entry!(
372 $layer,
373 $V,
374 $VC,
375 value,
376 context,
377 value_shared,
378 has_generics,
379 value_info.as_ref()
380 )?;
381 pair_count += 1;
382 if pair_count == MAX_CHUNK_SIZE {
383 context.writer.set_bytes(header_offset + 1, &[pair_count]);
384 pair_count = 0;
385 need_header = true;
386 key_type = None;
387 value_type = None;
388 key_info = None;
389 value_info = None;
390 }
391 }
392 if pair_count != 0 {
393 context.writer.set_bytes(header_offset + 1, &[pair_count]);
394 }
395 check_count_write_bytes(context, body_offset, len)
396 }};
397}
398
399fn write_value_map_data<'a, K, V, KS, VS, I>(
400 iter: I,
401 len: usize,
402 context: &mut WriteContext,
403) -> Result<(), Error>
404where
405 K: 'static + 'a,
406 V: 'static + 'a,
407 KS: Serializer<Target = K>,
408 VS: Serializer<Target = V>,
409 I: Iterator<Item = (&'a K, &'a V)>,
410{
411 write_map_data_body!(value, K, V, KS, VS, iter, len, context, false)
412}
413
414fn write_field_map_data<'a, K, V, KC, VC, I>(
415 iter: I,
416 len: usize,
417 context: &mut WriteContext,
418 has_generics: bool,
419) -> Result<(), Error>
420where
421 K: 'static + 'a,
422 V: 'static + 'a,
423 KC: Codec<K>,
424 VC: Codec<V>,
425 I: Iterator<Item = (&'a K, &'a V)>,
426{
427 write_map_data_body!(field, K, V, KC, VC, iter, len, context, has_generics)
428}
429
430enum EntryReadType<'a> {
431 Direct,
432 Field(Cow<'a, FieldType>),
433 TypeInfo(Rc<TypeInfo>),
434}
435
436#[inline(always)]
437fn read_value_entry_type<T, S>(
438 context: &mut ReadContext,
439 declared: bool,
440) -> Result<Option<Rc<TypeInfo>>, Error>
441where
442 T: 'static,
443 S: Serializer<Target = T>,
444{
445 if declared {
446 return Ok(None);
447 }
448 read_value_type_info::<S>(context)
449}
450
451#[inline(always)]
452fn read_value_entry<T, S>(
453 context: &mut ReadContext,
454 read_type: &Option<Rc<TypeInfo>>,
455 track_ref: bool,
456) -> Result<T, Error>
457where
458 T: 'static,
459 S: Serializer<Target = T>,
460{
461 let ref_mode = if track_ref {
462 RefMode::Tracking
463 } else {
464 RefMode::None
465 };
466 match read_type {
467 None => S::read(context, ref_mode, false),
468 Some(type_info) => S::read_with_type_info(context, ref_mode, type_info),
469 }
470}
471
472#[inline(always)]
473fn read_entry_type<'a, T: 'static, C: Codec<T>>(
474 context: &mut ReadContext,
475 declared: bool,
476 remote_field_type: Option<&'a FieldType>,
477 index: usize,
478 track_ref: bool,
479) -> Result<EntryReadType<'a>, Error> {
480 if declared {
481 return match remote_field_type {
482 Some(field_type) => {
483 let field_type = generic_field_type(field_type, index, "map")?;
484 Ok(EntryReadType::Field(field_type_with_ref_flags(
485 field_type,
486 field_type.nullable,
487 track_ref,
488 )))
489 }
490 None => Ok(EntryReadType::Direct),
491 };
492 }
493 match C::read_type_info_value(context)? {
494 CodecReadType::Field(mut field_type) => {
495 field_type.track_ref = track_ref;
496 Ok(EntryReadType::Field(Cow::Owned(field_type)))
497 }
498 CodecReadType::TypeInfo(type_info) => Ok(EntryReadType::TypeInfo(type_info)),
499 }
500}
501
502#[inline(always)]
503fn read_entry<T: 'static, C: Codec<T>>(
504 context: &mut ReadContext,
505 read_type: &EntryReadType<'_>,
506 track_ref: bool,
507) -> Result<T, Error> {
508 let ref_mode = if track_ref {
509 RefMode::Tracking
510 } else {
511 RefMode::None
512 };
513 match read_type {
514 EntryReadType::Direct => C::read(context, ref_mode, false),
515 EntryReadType::TypeInfo(type_info) => C::read_with_type_info(context, ref_mode, type_info),
516 EntryReadType::Field(field_type) if track_ref => {
517 C::read_field_with_type(context, field_type)
518 }
519 EntryReadType::Field(field_type) => C::read_data_with_type(context, field_type),
520 }
521}
522
523macro_rules! map_read_mode {
524 (value, $T:ty, $S:ty, $context:expr, $ref_mode:expr, $read_type:expr) => {
525 <$S as Serializer>::read($context, $ref_mode, $read_type)
526 };
527 (field, $T:ty, $C:ty, $context:expr, $ref_mode:expr, $read_type:expr) => {
528 <$C as Serializer>::read($context, $ref_mode, $read_type)
529 };
530}
531
532macro_rules! map_read_entry_type {
533 (value, $T:ty, $S:ty, $context:expr, $declared:expr, $remote:expr, $index:expr, $tracked:expr) => {
534 read_value_entry_type::<$T, $S>($context, $declared)
535 };
536 (field, $T:ty, $C:ty, $context:expr, $declared:expr, $remote:expr, $index:expr, $tracked:expr) => {
537 read_entry_type::<$T, $C>($context, $declared, $remote, $index, $tracked)
538 };
539}
540
541macro_rules! map_read_entry {
542 (value, $T:ty, $S:ty, $context:expr, $read_type:expr, $tracked:expr) => {
543 read_value_entry::<$T, $S>($context, $read_type, $tracked)
544 };
545 (field, $T:ty, $C:ty, $context:expr, $read_type:expr, $tracked:expr) => {
546 read_entry::<$T, $C>($context, $read_type, $tracked)
547 };
548}
549
550#[cold]
551#[inline(never)]
552fn invalid_map_chunk() -> Error {
553 Error::invalid_data("map chunk size must be within the remaining entry count")
554}
555
556#[cold]
557#[inline(never)]
558fn map_memory_overflow() -> Error {
559 Error::invalid_data("graph memory estimate overflows")
560}
561
562#[cold]
563#[inline(never)]
564fn map_type_mismatch(remote: u32) -> Error {
565 Error::type_mismatch(TypeId::MAP as u32, remote)
566}
567
568macro_rules! read_map_data_body {
569 (
570 $layer:ident,
571 $M:ident,
572 $K:ident,
573 $V:ident,
574 $KC:ident,
575 $VC:ident,
576 $context:expr,
577 $remote_field_type:expr
578 ) => {{
579 let context = $context;
580 let len = context.reader.read_var_u32()?;
581 let capacity = len as usize;
582 context.reader.check_bound(capacity)?;
583 let elem_bytes = std::mem::size_of::<$K>()
584 .checked_add(std::mem::size_of::<$V>())
585 .and_then(|bytes| bytes.checked_mul(capacity))
586 .ok_or_else(map_memory_overflow)?;
587 context.reserve_graph_memory(elem_bytes)?;
588 let mut map = $M::with_capacity(capacity);
589 let mut read = 0u32;
590 while read < len {
591 let header = context.reader.read_u8()?;
592 if header & KEY_NULL != 0 && header & VALUE_NULL != 0 {
593 map.insert($KC::default_value(context)?, $VC::default_value(context)?);
594 read += 1;
595 continue;
596 }
597 let key_declared = header & DECL_KEY_TYPE != 0;
598 let value_declared = header & DECL_VALUE_TYPE != 0;
599 let key_tracked = header & TRACKING_KEY_REF != 0;
600 let value_tracked = header & TRACKING_VALUE_REF != 0;
601 if header & KEY_NULL != 0 {
602 let value = if value_tracked && !value_declared {
603 map_read_mode!($layer, $V, $VC, context, RefMode::Tracking, true)?
604 } else {
605 let value_type = map_read_entry_type!(
606 $layer,
607 $V,
608 $VC,
609 context,
610 value_declared,
611 $remote_field_type,
612 1,
613 value_tracked
614 )?;
615 map_read_entry!($layer, $V, $VC, context, &value_type, value_tracked)?
616 };
617 map.insert($KC::default_value(context)?, value);
618 read += 1;
619 continue;
620 }
621 if header & VALUE_NULL != 0 {
622 let key = if key_tracked && !key_declared {
623 map_read_mode!($layer, $K, $KC, context, RefMode::Tracking, true)?
624 } else {
625 let key_type = map_read_entry_type!(
626 $layer,
627 $K,
628 $KC,
629 context,
630 key_declared,
631 $remote_field_type,
632 0,
633 key_tracked
634 )?;
635 map_read_entry!($layer, $K, $KC, context, &key_type, key_tracked)?
636 };
637 map.insert(key, $VC::default_value(context)?);
638 read += 1;
639 continue;
640 }
641 let chunk_size = context.reader.read_u8()? as u32;
642 if chunk_size == 0 {
643 return Err(invalid_map_chunk());
644 }
645 let end = read
646 .checked_add(chunk_size)
647 .filter(|end| *end <= len)
648 .ok_or_else(invalid_map_chunk)?;
649 let key_type = map_read_entry_type!(
650 $layer,
651 $K,
652 $KC,
653 context,
654 key_declared,
655 $remote_field_type,
656 0,
657 key_tracked
658 )?;
659 let value_type = map_read_entry_type!(
660 $layer,
661 $V,
662 $VC,
663 context,
664 value_declared,
665 $remote_field_type,
666 1,
667 value_tracked
668 )?;
669 while read < end {
670 let key = map_read_entry!($layer, $K, $KC, context, &key_type, key_tracked)?;
671 let value = map_read_entry!($layer, $V, $VC, context, &value_type, value_tracked)?;
672 map.insert(key, value);
673 read += 1;
674 }
675 }
676 Ok(map)
677 }};
678}
679
680fn read_value_map_data<M, K, V, KS, VS>(context: &mut ReadContext) -> Result<M, Error>
681where
682 K: 'static,
683 V: 'static,
684 KS: Serializer<Target = K>,
685 VS: Serializer<Target = V>,
686 M: MapTarget<K, V>,
687{
688 read_map_data_body!(value, M, K, V, KS, VS, context, ())
689}
690
691fn read_field_map_data<M, K, V, KC, VC>(
692 context: &mut ReadContext,
693 remote_field_type: Option<&FieldType>,
694) -> Result<M, Error>
695where
696 K: 'static,
697 V: 'static,
698 KC: Codec<K>,
699 VC: Codec<V>,
700 M: MapTarget<K, V>,
701{
702 read_map_data_body!(field, M, K, V, KC, VC, context, remote_field_type)
703}
704
705macro_rules! impl_map_codec {
706 ($codec:ident, $target:ident, [$($key_bound:tt)+]) => {
707 impl<K, V, KS, VS, const NULLABLE: bool, const TRACK_REF: bool> Serializer
708 for $codec<K, V, KS, VS, NULLABLE, TRACK_REF>
709 where
710 K: $($key_bound)+ + 'static,
711 V: 'static,
712 KS: Serializer<Target = K>,
713 VS: Serializer<Target = V>,
714 {
715 type Target = $target<K, V>;
716
717 #[inline(always)]
718 fn write_data(
719 value: &Self::Target,
720 context: &mut WriteContext,
721 ) -> Result<(), Error> {
722 write_value_map_data::<K, V, KS, VS, _>(
723 value.iter(),
724 value.len(),
725 context,
726 )
727 }
728
729 #[inline(always)]
730 fn read_data(context: &mut ReadContext) -> Result<Self::Target, Error> {
731 read_value_map_data::<Self::Target, K, V, KS, VS>(context)
732 }
733
734 #[inline(always)]
735 fn default_value(_: &mut ReadContext) -> Result<Self::Target, Error> {
736 Ok(<Self::Target as MapTarget<K, V>>::with_capacity(0))
737 }
738
739 #[inline(always)]
740 fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
741 context.writer.write_u8(TypeId::MAP as u8);
742 Ok(())
743 }
744
745 #[inline(always)]
746 fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
747 let remote = context.reader.read_u8()? as u32;
748 if remote == TypeId::MAP as u32 {
749 Ok(())
750 } else {
751 Err(map_type_mismatch(remote))
752 }
753 }
754
755 #[inline(always)]
756 fn static_type_id() -> TypeId {
757 TypeId::MAP
758 }
759
760 #[inline(always)]
761 fn reserved_space() -> usize {
762 std::mem::size_of::<u32>() + SIZE_OF_REF_AND_TYPE
763 }
764 }
765
766 impl<K, V, KC, VC, const NULLABLE: bool, const TRACK_REF: bool>
767 Codec<$target<K, V>> for $codec<K, V, KC, VC, NULLABLE, TRACK_REF>
768 where
769 K: $($key_bound)+ + 'static,
770 V: 'static,
771 KC: Codec<K>,
772 VC: Codec<V>,
773 {
774 #[inline(always)]
775 fn field_type(type_resolver: &TypeResolver) -> Result<FieldType, Error> {
776 Ok(FieldType::new_with_ref(
777 TypeId::MAP as u32,
778 NULLABLE,
779 TRACK_REF,
780 vec![
781 KC::field_type(type_resolver)?,
782 VC::field_type(type_resolver)?,
783 ],
784 ))
785 }
786
787 #[inline(always)]
788 fn write_field(
789 value: &$target<K, V>,
790 context: &mut WriteContext,
791 ) -> Result<(), Error> {
792 if NULLABLE || TRACK_REF {
793 context.writer.write_i8(RefFlag::NotNullValue as i8);
794 }
795 write_field_map_data::<K, V, KC, VC, _>(
796 value.iter(),
797 value.len(),
798 context,
799 true,
800 )
801 }
802
803 #[inline(always)]
804 fn read_field(context: &mut ReadContext) -> Result<$target<K, V>, Error> {
805 if (NULLABLE || TRACK_REF)
806 && context.reader.read_i8()? == RefFlag::Null as i8
807 {
808 return Ok(
809 <$target<K, V> as MapTarget<K, V>>::with_capacity(0)
810 );
811 }
812 <Self as Serializer>::read_data(context)
813 }
814
815 #[inline(always)]
816 fn read_data_with_type(
817 context: &mut ReadContext,
818 remote_data_type: &FieldType,
819 ) -> Result<$target<K, V>, Error> {
820 read_field_map_data::<$target<K, V>, K, V, KC, VC>(
821 context,
822 Some(remote_data_type),
823 )
824 }
825
826 #[inline(always)]
827 fn read_field_with_type(
828 context: &mut ReadContext,
829 remote_field_type: &FieldType,
830 ) -> Result<$target<K, V>, Error> {
831 if field_ref_mode(remote_field_type) != RefMode::None
832 && context.reader.read_i8()? == RefFlag::Null as i8
833 {
834 return Ok(
835 <$target<K, V> as MapTarget<K, V>>::with_capacity(0)
836 );
837 }
838 Self::read_data_with_type(context, remote_field_type)
839 }
840
841 #[inline(always)]
842 fn write_with_mode(
843 value: &$target<K, V>,
844 context: &mut WriteContext,
845 ref_mode: RefMode,
846 write_type_info: bool,
847 has_generics: bool,
848 ) -> Result<(), Error> {
849 if !has_generics {
850 return <Self as Serializer>::write(
851 value,
852 context,
853 ref_mode,
854 write_type_info,
855 );
856 }
857 if ref_mode != RefMode::None {
858 context.writer.write_i8(RefFlag::NotNullValue as i8);
859 }
860 if write_type_info {
861 <Self as Serializer>::write_type_info(context)?;
862 }
863 write_field_map_data::<K, V, KC, VC, _>(
864 value.iter(),
865 value.len(),
866 context,
867 true,
868 )
869 }
870 }
871 };
872}
873
874impl_map_codec!(HashMapCodec, HashMap, [Eq + std::hash::Hash]);
875impl_map_codec!(BTreeMapCodec, BTreeMap, [Ord]);
876
877macro_rules! impl_map_serializer {
878 ($provider:ident, $target:ident, $codec:ident, [$($key_bound:tt)+]) => {
879 #[doc = concat!(
880 "Statically serializes `",
881 stringify!($target),
882 "<KS::Target, VS::Target>` at roots or recursive carrier nodes. ",
883 "This zero-sized carrier composes its key and value serializers and is not ",
884 "registered independently."
885 )]
886 pub struct $provider<KS, VS>(PhantomData<fn() -> (KS, VS)>);
887
888 impl<KS, VS> Serializer for $provider<KS, VS>
889 where
890 KS: Serializer,
891 VS: Serializer,
892 KS::Target: $($key_bound)+,
893 {
894 type Target = $target<KS::Target, VS::Target>;
895
896 #[inline(always)]
897 fn write_data(value: &Self::Target, context: &mut WriteContext) -> Result<(), Error> {
898 <$codec<
899 KS::Target,
900 VS::Target,
901 KS,
902 VS,
903 false,
904 false,
905 > as Serializer>::write_data(value, context)
906 }
907
908 #[inline(always)]
909 fn read_data(context: &mut ReadContext) -> Result<Self::Target, Error> {
910 <$codec<
911 KS::Target,
912 VS::Target,
913 KS,
914 VS,
915 false,
916 false,
917 > as Serializer>::read_data(context)
918 }
919
920 #[inline(always)]
921 fn default_value(context: &mut ReadContext) -> Result<Self::Target, Error> {
922 <$codec<
923 KS::Target,
924 VS::Target,
925 KS,
926 VS,
927 false,
928 false,
929 > as Serializer>::default_value(context)
930 }
931
932 #[inline(always)]
933 fn write(
934 value: &Self::Target,
935 context: &mut WriteContext,
936 ref_mode: RefMode,
937 write_type_info: bool,
938 ) -> Result<(), Error> {
939 <$codec<
940 KS::Target,
941 VS::Target,
942 KS,
943 VS,
944 false,
945 false,
946 > as Serializer>::write(
947 value,
948 context,
949 ref_mode,
950 write_type_info,
951 )
952 }
953
954 #[inline(always)]
955 fn read(
956 context: &mut ReadContext,
957 ref_mode: RefMode,
958 read_type_info: bool,
959 ) -> Result<Self::Target, Error> {
960 <$codec<
961 KS::Target,
962 VS::Target,
963 KS,
964 VS,
965 false,
966 false,
967 > as Serializer>::read(
968 context,
969 ref_mode,
970 read_type_info,
971 )
972 }
973
974 #[inline(always)]
975 fn read_with_type_info(
976 context: &mut ReadContext,
977 ref_mode: RefMode,
978 type_info: &Rc<TypeInfo>,
979 ) -> Result<Self::Target, Error> {
980 <$codec<
981 KS::Target,
982 VS::Target,
983 KS,
984 VS,
985 false,
986 false,
987 > as Serializer>::read_with_type_info(
988 context,
989 ref_mode,
990 type_info,
991 )
992 }
993
994 #[inline(always)]
995 fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
996 <$codec<
997 KS::Target,
998 VS::Target,
999 KS,
1000 VS,
1001 false,
1002 false,
1003 > as Serializer>::write_type_info(context)
1004 }
1005
1006 #[inline(always)]
1007 fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
1008 <$codec<
1009 KS::Target,
1010 VS::Target,
1011 KS,
1012 VS,
1013 false,
1014 false,
1015 > as Serializer>::read_type_info(context)
1016 }
1017
1018 #[inline(always)]
1019 fn static_type_id() -> TypeId {
1020 TypeId::MAP
1021 }
1022
1023 #[inline(always)]
1024 fn reserved_space() -> usize {
1025 std::mem::size_of::<u32>() + SIZE_OF_REF_AND_TYPE
1026 }
1027 }
1028
1029 impl<K, V> Serializer for $target<K, V>
1030 where
1031 K: Serializer<Target = K> + $($key_bound)+,
1032 V: Serializer<Target = V>,
1033 {
1034 type Target = Self;
1035
1036 #[inline(always)]
1037 fn write_data(value: &Self, context: &mut WriteContext) -> Result<(), Error> {
1038 <$provider<K, V> as Serializer>::write_data(value, context)
1039 }
1040
1041 #[inline(always)]
1042 fn read_data(context: &mut ReadContext) -> Result<Self, Error> {
1043 <$provider<K, V> as Serializer>::read_data(context)
1044 }
1045
1046 #[inline(always)]
1047 fn default_value(context: &mut ReadContext) -> Result<Self, Error> {
1048 <$provider<K, V> as Serializer>::default_value(context)
1049 }
1050
1051 #[inline(always)]
1052 fn write(
1053 value: &Self,
1054 context: &mut WriteContext,
1055 ref_mode: RefMode,
1056 write_type_info: bool,
1057 ) -> Result<(), Error> {
1058 <$provider<K, V> as Serializer>::write(
1059 value,
1060 context,
1061 ref_mode,
1062 write_type_info,
1063 )
1064 }
1065
1066 #[inline(always)]
1067 fn read(
1068 context: &mut ReadContext,
1069 ref_mode: RefMode,
1070 read_type_info: bool,
1071 ) -> Result<Self, Error> {
1072 <$provider<K, V> as Serializer>::read(
1073 context,
1074 ref_mode,
1075 read_type_info,
1076 )
1077 }
1078
1079 #[inline(always)]
1080 fn read_with_type_info(
1081 context: &mut ReadContext,
1082 ref_mode: RefMode,
1083 type_info: &Rc<TypeInfo>,
1084 ) -> Result<Self, Error> {
1085 <$provider<K, V> as Serializer>::read_with_type_info(
1086 context,
1087 ref_mode,
1088 type_info,
1089 )
1090 }
1091
1092 #[inline(always)]
1093 fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
1094 <$provider<K, V> as Serializer>::write_type_info(context)
1095 }
1096
1097 #[inline(always)]
1098 fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
1099 <$provider<K, V> as Serializer>::read_type_info(context)
1100 }
1101
1102 #[inline(always)]
1103 fn static_type_id() -> TypeId {
1104 TypeId::MAP
1105 }
1106
1107 #[inline(always)]
1108 fn reserved_space() -> usize {
1109 std::mem::size_of::<u32>() + SIZE_OF_REF_AND_TYPE
1110 }
1111 }
1112 };
1113}
1114
1115impl_map_serializer!(
1116 HashMapSerializer,
1117 HashMap,
1118 HashMapCodec,
1119 [Eq + std::hash::Hash]
1120);
1121impl_map_serializer!(BTreeMapSerializer, BTreeMap, BTreeMapCodec, [Ord]);