1use crate::ensure;
19use crate::error::Error;
20use crate::resolver::context::{ReadContext, WriteContext};
21use crate::resolver::type_resolver::{TypeInfo, TypeResolver};
22use crate::serializer::util::read_basic_type_info;
23use crate::serializer::{ForyDefault, Serializer};
24use crate::types::{need_to_write_type_for_field, RefMode, TypeId, SIZE_OF_REF_AND_TYPE};
25use std::collections::{BTreeMap, HashMap};
26use std::rc::Rc;
27
28const MAX_CHUNK_SIZE: u8 = 255;
29
30const TRACKING_KEY_REF: u8 = 0b1;
31pub const KEY_NULL: u8 = 0b10;
32pub const DECL_KEY_TYPE: u8 = 0b100;
33const TRACKING_VALUE_REF: u8 = 0b1000;
34pub const VALUE_NULL: u8 = 0b10000;
35pub const DECL_VALUE_TYPE: u8 = 0b100000;
36
37fn check_map_len(context: &ReadContext, len: u32) -> Result<(), Error> {
38 let len = len as usize;
39 let remaining = context.reader.slice_after_cursor().len();
40 if len > remaining {
41 let cursor = context.reader.get_cursor();
42 return Err(Error::buffer_out_of_bound(cursor, len, cursor + remaining));
43 }
44 Ok(())
45}
46
47fn write_chunk_size(context: &mut WriteContext, header_offset: usize, size: u8) {
48 context.writer.set_bytes(header_offset + 1, &[size]);
49}
50
51pub fn write_map_data<'a, K, V, I>(
52 iter: I,
53 length: usize,
54 context: &mut WriteContext,
55 has_generics: bool,
56) -> Result<(), Error>
57where
58 K: Serializer,
59 V: Serializer,
60 I: Iterator<Item = (&'a K, &'a V)>,
61{
62 context.writer.write_var_uint32(length as u32);
63 if length == 0 {
64 return Ok(());
65 }
66 let reserved_space = (K::fory_reserved_space() + SIZE_OF_REF_AND_TYPE) * length
67 + (V::fory_reserved_space() + SIZE_OF_REF_AND_TYPE) * length;
68 context.writer.reserve(reserved_space);
69
70 if K::fory_is_polymorphic()
71 || K::fory_is_shared_ref()
72 || V::fory_is_polymorphic()
73 || V::fory_is_shared_ref()
74 {
75 return write_map_data_dyn_ref(iter, context, has_generics);
76 }
77 let mut header_offset = 0;
78 let mut pair_counter: u8 = 0;
79 let mut need_write_header = true;
80 let key_static_type_id = K::fory_static_type_id();
81 let val_static_type_id = V::fory_static_type_id();
82 let is_key_declared = has_generics && !need_to_write_type_for_field(key_static_type_id);
83 let is_val_declared = has_generics && !need_to_write_type_for_field(val_static_type_id);
84 for (key, value) in iter {
85 let key_is_none = key.fory_is_none();
86 let value_is_none = value.fory_is_none();
87
88 if key_is_none || value_is_none {
89 if !need_write_header && pair_counter > 0 {
90 write_chunk_size(context, header_offset, pair_counter);
91 pair_counter = 0;
92 need_write_header = true;
93 }
94
95 if key_is_none && value_is_none {
96 context.writer.write_u8(KEY_NULL | VALUE_NULL);
97 continue;
98 }
99
100 if value_is_none {
101 let mut chunk_header = VALUE_NULL;
102 if is_key_declared {
103 chunk_header |= DECL_KEY_TYPE;
104 context.writer.write_u8(chunk_header);
105 } else {
106 context.writer.write_u8(chunk_header);
107 K::fory_write_type_info(context)?;
108 }
109 key.fory_write_data_generic(context, has_generics)?;
110 continue;
111 }
112
113 let mut chunk_header = KEY_NULL;
115 if is_val_declared {
116 chunk_header |= DECL_VALUE_TYPE;
117 context.writer.write_u8(chunk_header);
118 } else {
119 context.writer.write_u8(chunk_header);
120 V::fory_write_type_info(context)?;
121 }
122 value.fory_write_data_generic(context, has_generics)?;
123 continue;
124 }
125
126 if need_write_header {
127 header_offset = context.writer.len();
128 context.writer.write_i16(-1);
129 let mut chunk_header = 0u8;
130 if is_key_declared {
131 chunk_header |= DECL_KEY_TYPE;
132 } else {
133 K::fory_write_type_info(context)?;
134 }
135 if is_val_declared {
136 chunk_header |= DECL_VALUE_TYPE;
137 } else {
138 V::fory_write_type_info(context)?;
139 }
140 context.writer.set_bytes(header_offset, &[chunk_header]);
141 need_write_header = false;
142 }
143
144 key.fory_write_data_generic(context, has_generics)?;
145 value.fory_write_data_generic(context, has_generics)?;
146 pair_counter += 1;
147 if pair_counter == MAX_CHUNK_SIZE {
148 write_chunk_size(context, header_offset, pair_counter);
149 pair_counter = 0;
150 need_write_header = true;
151 }
152 }
153 if pair_counter > 0 {
154 write_chunk_size(context, header_offset, pair_counter);
155 }
156 Ok(())
157}
158
159fn write_map_data_dyn_ref<'a, K, V, I>(
161 iter: I,
162 context: &mut WriteContext,
163 has_generics: bool,
164) -> Result<(), Error>
165where
166 K: Serializer,
167 V: Serializer,
168 I: Iterator<Item = (&'a K, &'a V)>,
169{
170 let mut header_offset = 0;
171 let mut pair_counter: u8 = 0;
172 let mut need_write_header = true;
173 let key_static_type_id = K::fory_static_type_id();
174 let val_static_type_id = V::fory_static_type_id();
175 let is_key_declared = has_generics && !need_to_write_type_for_field(key_static_type_id);
176 let is_val_declared = has_generics && !need_to_write_type_for_field(val_static_type_id);
177 let key_is_polymorphic = K::fory_is_polymorphic();
178 let val_is_polymorphic = V::fory_is_polymorphic();
179 let key_is_shared_ref = K::fory_is_shared_ref();
180 let val_is_shared_ref = V::fory_is_shared_ref();
181
182 let mut current_key_type_id: Option<std::any::TypeId> = None;
184 let mut current_val_type_id: Option<std::any::TypeId> = None;
185
186 for (key, value) in iter {
187 if key.fory_is_none() || value.fory_is_none() {
189 if pair_counter > 0 {
191 write_chunk_size(context, header_offset, pair_counter);
192 pair_counter = 0;
193 need_write_header = true;
194 }
195
196 if key.fory_is_none() && value.fory_is_none() {
197 context.writer.write_u8(KEY_NULL | VALUE_NULL);
198 continue;
199 } else if value.fory_is_none() {
200 let mut chunk_header = VALUE_NULL;
201 if key_is_shared_ref {
202 chunk_header |= TRACKING_KEY_REF;
203 }
204 if is_key_declared && !key_is_polymorphic {
205 chunk_header |= DECL_KEY_TYPE;
206 context.writer.write_u8(chunk_header);
207 } else {
208 context.writer.write_u8(chunk_header);
209 if key_is_polymorphic {
210 context.write_any_type_info(
211 K::fory_static_type_id() as u32,
212 key.fory_concrete_type_id(),
213 )?;
214 } else {
215 K::fory_write_type_info(context)?;
216 }
217 }
218 if key_is_shared_ref {
219 key.fory_write(context, RefMode::Tracking, false, has_generics)?;
220 } else {
221 key.fory_write_data_generic(context, has_generics)?;
222 }
223 continue;
224 } else {
225 let mut chunk_header = KEY_NULL;
227 if val_is_shared_ref {
228 chunk_header |= TRACKING_VALUE_REF;
229 }
230 if is_val_declared && !val_is_polymorphic {
231 chunk_header |= DECL_VALUE_TYPE;
232 context.writer.write_u8(chunk_header);
233 } else {
234 context.writer.write_u8(chunk_header);
235 if val_is_polymorphic {
236 context.write_any_type_info(
237 V::fory_static_type_id() as u32,
238 value.fory_concrete_type_id(),
239 )?;
240 } else {
241 V::fory_write_type_info(context)?;
242 }
243 }
244 if val_is_shared_ref {
245 value.fory_write(context, RefMode::Tracking, false, has_generics)?;
246 } else {
247 value.fory_write_data_generic(context, has_generics)?;
248 }
249 continue;
250 }
251 }
252
253 let key_type_id = if key_is_polymorphic {
255 Some(key.fory_concrete_type_id())
256 } else {
257 None
258 };
259 let val_type_id = if val_is_polymorphic {
260 Some(value.fory_concrete_type_id())
261 } else {
262 None
263 };
264
265 let types_changed = if key_is_polymorphic || val_is_polymorphic {
267 key_type_id != current_key_type_id || val_type_id != current_val_type_id
268 } else {
269 false
270 };
271
272 if need_write_header || types_changed {
273 if types_changed && pair_counter > 0 {
275 write_chunk_size(context, header_offset, pair_counter);
276 pair_counter = 0;
277 }
278
279 header_offset = context.writer.len();
281 context.writer.write_i16(-1); let mut chunk_header = 0u8;
284
285 if key_is_shared_ref {
287 chunk_header |= TRACKING_KEY_REF;
288 }
289 if is_key_declared && !key_is_polymorphic {
290 chunk_header |= DECL_KEY_TYPE;
291 } else {
292 if key_is_polymorphic {
294 context.write_any_type_info(
295 K::fory_static_type_id() as u32,
296 key.fory_concrete_type_id(),
297 )?;
298 } else {
299 K::fory_write_type_info(context)?;
300 }
301 }
302
303 if val_is_shared_ref {
305 chunk_header |= TRACKING_VALUE_REF;
306 }
307 if is_val_declared && !val_is_polymorphic {
308 chunk_header |= DECL_VALUE_TYPE;
309 } else {
310 if val_is_polymorphic {
312 context.write_any_type_info(
313 V::fory_static_type_id() as u32,
314 value.fory_concrete_type_id(),
315 )?;
316 } else {
317 V::fory_write_type_info(context)?;
318 }
319 }
320
321 context.writer.set_bytes(header_offset, &[chunk_header]);
322 need_write_header = false;
323 current_key_type_id = key_type_id;
324 current_val_type_id = val_type_id;
325 }
326
327 if key_is_shared_ref {
329 key.fory_write(context, RefMode::Tracking, false, has_generics)?;
330 } else {
331 key.fory_write_data_generic(context, has_generics)?;
332 }
333 if val_is_shared_ref {
334 value.fory_write(context, RefMode::Tracking, false, has_generics)?;
335 } else {
336 value.fory_write_data_generic(context, has_generics)?;
337 }
338 pair_counter += 1;
339 if pair_counter == MAX_CHUNK_SIZE {
340 write_chunk_size(context, header_offset, pair_counter);
341 pair_counter = 0;
342 need_write_header = true;
343 current_key_type_id = None;
344 current_val_type_id = None;
345 }
346 }
347
348 if pair_counter > 0 {
350 write_chunk_size(context, header_offset, pair_counter);
351 }
352
353 Ok(())
354}
355
356macro_rules! impl_read_map_dyn_ref {
359 ($fn_name:ident, $map_type:ty, $($extra_trait_bounds:tt)*) => {
360 fn $fn_name<K, V>(
361 context: &mut ReadContext,
362 mut map: $map_type,
363 length: u32,
364 ) -> Result<$map_type, Error>
365 where
366 K: Serializer + ForyDefault + $($extra_trait_bounds)*,
367 V: Serializer + ForyDefault,
368 {
369 let key_is_polymorphic = K::fory_is_polymorphic();
370 let val_is_polymorphic = V::fory_is_polymorphic();
371 let mut len_counter = 0u32;
372
373 while len_counter < length {
374 let header = context.reader.read_u8()?;
375
376 if header & KEY_NULL != 0 && header & VALUE_NULL != 0 {
378 map.insert(K::fory_default(), V::fory_default());
380 len_counter += 1;
381 continue;
382 }
383
384 if header & KEY_NULL != 0 {
385 let value_declared = (header & DECL_VALUE_TYPE) != 0;
387 let track_value_ref = (header & TRACKING_VALUE_REF) != 0;
388
389 let value_type_info: Option<Rc<TypeInfo>> = if !value_declared {
391 if val_is_polymorphic {
392 Some(context.read_any_type_info()?)
393 } else {
394 V::fory_read_type_info(context)?;
395 None
396 }
397 } else {
398 None
399 };
400
401 let ref_mode = if track_value_ref {
403 RefMode::Tracking
404 } else {
405 RefMode::None
406 };
407 let value = if let Some(type_info) = value_type_info {
408 V::fory_read_with_type_info(context, ref_mode, type_info)?
409 } else if track_value_ref {
410 V::fory_read(context, ref_mode, false)?
411 } else {
412 V::fory_read_data(context)?
413 };
414
415 map.insert(K::fory_default(), value);
416 len_counter += 1;
417 continue;
418 }
419
420 if header & VALUE_NULL != 0 {
421 let key_declared = (header & DECL_KEY_TYPE) != 0;
423 let track_key_ref = (header & TRACKING_KEY_REF) != 0;
424
425 let key_type_info: Option<Rc<TypeInfo>> = if !key_declared {
426 if key_is_polymorphic {
427 Some(context.read_any_type_info()?)
428 } else {
429 K::fory_read_type_info(context)?;
430 None
431 }
432 } else {
433 None
434 };
435
436 let ref_mode = if track_key_ref {
437 RefMode::Tracking
438 } else {
439 RefMode::None
440 };
441 let key = if let Some(type_info) = key_type_info {
442 K::fory_read_with_type_info(context, ref_mode, type_info)?
443 } else if track_key_ref {
444 K::fory_read(context, ref_mode, false)?
445 } else {
446 K::fory_read_data(context)?
447 };
448
449 map.insert(key, V::fory_default());
450 len_counter += 1;
451 continue;
452 }
453
454 let chunk_size = context.reader.read_u8()?;
456 let key_declared = (header & DECL_KEY_TYPE) != 0;
457 let value_declared = (header & DECL_VALUE_TYPE) != 0;
458 let track_key_ref = (header & TRACKING_KEY_REF) != 0;
459 let track_value_ref = (header & TRACKING_VALUE_REF) != 0;
460
461 let key_type_info: Option<Rc<TypeInfo>> = if !key_declared {
462 if key_is_polymorphic {
463 Some(context.read_any_type_info()?)
464 } else {
465 K::fory_read_type_info(context)?;
466 None
467 }
468 } else {
469 None
470 };
471 let value_type_info: Option<Rc<TypeInfo>> = if !value_declared {
472 if val_is_polymorphic {
473 Some(context.read_any_type_info()?)
474 } else {
475 V::fory_read_type_info(context)?;
476 None
477 }
478 } else {
479 None
480 };
481
482 let cur_len = len_counter + chunk_size as u32;
483 ensure!(
484 cur_len <= length,
485 Error::invalid_data(
486 format!("current length {} exceeds total length {}", cur_len, length)
487 )
488 );
489
490 let key_ref_mode = if track_key_ref {
492 RefMode::Tracking
493 } else {
494 RefMode::None
495 };
496 let val_ref_mode = if track_value_ref {
497 RefMode::Tracking
498 } else {
499 RefMode::None
500 };
501 for _ in 0..chunk_size {
502 let key = if let Some(type_info) = key_type_info.as_ref() {
503 K::fory_read_with_type_info(context, key_ref_mode, type_info.clone())?
504 } else if track_key_ref {
505 K::fory_read(context, key_ref_mode, false)?
506 } else {
507 K::fory_read_data(context)?
508 };
509
510 let value = if let Some(type_info) = value_type_info.as_ref() {
511 V::fory_read_with_type_info(context, val_ref_mode, type_info.clone())?
512 } else if track_value_ref {
513 V::fory_read(context, val_ref_mode, false)?
514 } else {
515 V::fory_read_data(context)?
516 };
517
518 map.insert(key, value);
519 }
520
521 len_counter += chunk_size as u32;
522 }
523
524 Ok(map)
525 }
526 };
527}
528
529impl_read_map_dyn_ref!(
531 read_hashmap_data_dyn_ref,
532 HashMap<K, V>,
533 Eq + std::hash::Hash
534);
535
536impl_read_map_dyn_ref!(
538 read_btreemap_data_dyn_ref,
539 BTreeMap<K, V>,
540 Ord
541);
542
543impl<K: Serializer + ForyDefault + Eq + std::hash::Hash, V: Serializer + ForyDefault> Serializer
544 for HashMap<K, V>
545{
546 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
547 write_map_data(self.iter(), self.len(), context, false)
548 }
549
550 fn fory_write_data_generic(
551 &self,
552 context: &mut WriteContext,
553 has_generics: bool,
554 ) -> Result<(), Error> {
555 write_map_data(self.iter(), self.len(), context, has_generics)
556 }
557
558 fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
559 let len = context.reader.read_varuint32()?;
560 if len == 0 {
561 return Ok(HashMap::new());
562 }
563 check_map_len(context, len)?;
564 if K::fory_is_polymorphic()
565 || K::fory_is_shared_ref()
566 || V::fory_is_polymorphic()
567 || V::fory_is_shared_ref()
568 {
569 let map: HashMap<K, V> = HashMap::with_capacity(len as usize);
570 return read_hashmap_data_dyn_ref(context, map, len);
571 }
572 let mut map = HashMap::<K, V>::with_capacity(len as usize);
573 let mut len_counter = 0;
574 loop {
575 if len_counter == len {
576 break;
577 }
578 let header = context.reader.read_u8()?;
579 if header & KEY_NULL != 0 && header & VALUE_NULL != 0 {
580 map.insert(K::fory_default(), V::fory_default());
581 len_counter += 1;
582 continue;
583 }
584 let key_declared = (header & DECL_KEY_TYPE) != 0;
585 let value_declared = (header & DECL_VALUE_TYPE) != 0;
586 let track_key_ref = (header & TRACKING_KEY_REF) != 0;
587 let track_value_ref = (header & TRACKING_VALUE_REF) != 0;
588 if header & KEY_NULL != 0 {
589 let ref_mode = if track_value_ref {
591 RefMode::Tracking
592 } else {
593 RefMode::None
594 };
595 let value = V::fory_read(context, ref_mode, !value_declared)?;
596 map.insert(K::fory_default(), value);
597 len_counter += 1;
598 continue;
599 }
600 if header & VALUE_NULL != 0 {
601 let ref_mode = if track_key_ref {
603 RefMode::Tracking
604 } else {
605 RefMode::None
606 };
607 let key = K::fory_read(context, ref_mode, !key_declared)?;
608 map.insert(key, V::fory_default());
609 len_counter += 1;
610 continue;
611 }
612 let chunk_size = context.reader.read_u8()?;
613 if header & DECL_KEY_TYPE == 0 {
614 K::fory_read_type_info(context)?;
615 }
616 if header & DECL_VALUE_TYPE == 0 {
617 V::fory_read_type_info(context)?;
618 }
619 let cur_len = len_counter + chunk_size as u32;
620 ensure!(
621 cur_len <= len,
622 Error::invalid_data(format!(
623 "current length {} exceeds total length {}",
624 cur_len, len
625 ))
626 );
627 if !track_key_ref && !track_value_ref {
628 for _ in 0..chunk_size {
629 let key = K::fory_read_data(context)?;
630 let value = V::fory_read_data(context)?;
631 map.insert(key, value);
632 }
633 } else {
634 let key_ref_mode = if track_key_ref {
635 RefMode::Tracking
636 } else {
637 RefMode::None
638 };
639 let val_ref_mode = if track_value_ref {
640 RefMode::Tracking
641 } else {
642 RefMode::None
643 };
644 for _ in 0..chunk_size {
645 let key = K::fory_read(context, key_ref_mode, false)?;
646 let value = V::fory_read(context, val_ref_mode, false)?;
647 map.insert(key, value);
648 }
649 }
650 len_counter += chunk_size as u32;
652 }
653 Ok(map)
654 }
655
656 fn fory_reserved_space() -> usize {
657 size_of::<i32>()
658 }
659
660 fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
661 Ok(TypeId::MAP)
662 }
663
664 fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
665 Ok(TypeId::MAP)
666 }
667
668 fn fory_static_type_id() -> TypeId
669 where
670 Self: Sized,
671 {
672 TypeId::MAP
673 }
674
675 fn as_any(&self) -> &dyn std::any::Any {
676 self
677 }
678
679 fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
680 context.writer.write_u8(TypeId::MAP as u8);
681 Ok(())
682 }
683
684 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
685 read_basic_type_info::<Self>(context)
686 }
687}
688
689impl<K, V> ForyDefault for HashMap<K, V> {
690 fn fory_default() -> Self {
691 HashMap::new()
692 }
693}
694
695impl<K: Serializer + ForyDefault + Ord + std::hash::Hash, V: Serializer + ForyDefault> Serializer
696 for BTreeMap<K, V>
697{
698 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
699 write_map_data(self.iter(), self.len(), context, false)
700 }
701
702 fn fory_write_data_generic(
703 &self,
704 context: &mut WriteContext,
705 has_generics: bool,
706 ) -> Result<(), Error> {
707 write_map_data(self.iter(), self.len(), context, has_generics)
708 }
709
710 fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
711 let len = context.reader.read_varuint32()?;
712 if len == 0 {
713 return Ok(BTreeMap::new());
714 }
715 check_map_len(context, len)?;
716 let mut map = BTreeMap::<K, V>::new();
717 if K::fory_is_polymorphic()
718 || K::fory_is_shared_ref()
719 || V::fory_is_polymorphic()
720 || V::fory_is_shared_ref()
721 {
722 let map: BTreeMap<K, V> = BTreeMap::new();
723 return read_btreemap_data_dyn_ref(context, map, len);
724 }
725 let mut len_counter = 0;
726 loop {
727 if len_counter == len {
728 break;
729 }
730 let header = context.reader.read_u8()?;
731 if header & KEY_NULL != 0 && header & VALUE_NULL != 0 {
732 map.insert(K::fory_default(), V::fory_default());
733 len_counter += 1;
734 continue;
735 }
736 let key_declared = (header & DECL_KEY_TYPE) != 0;
737 let value_declared = (header & DECL_VALUE_TYPE) != 0;
738 let track_key_ref = (header & TRACKING_KEY_REF) != 0;
739 let track_value_ref = (header & TRACKING_VALUE_REF) != 0;
740 if header & KEY_NULL != 0 {
741 let ref_mode = if track_value_ref {
743 RefMode::Tracking
744 } else {
745 RefMode::None
746 };
747 let value = V::fory_read(context, ref_mode, !value_declared)?;
748 map.insert(K::fory_default(), value);
749 len_counter += 1;
750 continue;
751 }
752 if header & VALUE_NULL != 0 {
753 let ref_mode = if track_key_ref {
755 RefMode::Tracking
756 } else {
757 RefMode::None
758 };
759 let key = K::fory_read(context, ref_mode, !key_declared)?;
760 map.insert(key, V::fory_default());
761 len_counter += 1;
762 continue;
763 }
764 let chunk_size = context.reader.read_u8()?;
765 if header & DECL_KEY_TYPE == 0 {
766 K::fory_read_type_info(context)?;
767 }
768 if header & DECL_VALUE_TYPE == 0 {
769 V::fory_read_type_info(context)?;
770 }
771 let cur_len = len_counter + chunk_size as u32;
772 ensure!(
773 cur_len <= len,
774 Error::invalid_data(format!(
775 "current length {} exceeds total length {}",
776 cur_len, len
777 ))
778 );
779 if !track_key_ref && !track_value_ref {
780 for _ in 0..chunk_size {
781 let key = K::fory_read_data(context)?;
782 let value = V::fory_read_data(context)?;
783 map.insert(key, value);
784 }
785 } else {
786 let key_ref_mode = if track_key_ref {
787 RefMode::Tracking
788 } else {
789 RefMode::None
790 };
791 let val_ref_mode = if track_value_ref {
792 RefMode::Tracking
793 } else {
794 RefMode::None
795 };
796 for _ in 0..chunk_size {
797 let key = K::fory_read(context, key_ref_mode, false)?;
798 let value = V::fory_read(context, val_ref_mode, false)?;
799 map.insert(key, value);
800 }
801 }
802 len_counter += chunk_size as u32;
803 }
804 Ok(map)
805 }
806
807 fn fory_reserved_space() -> usize {
808 size_of::<i32>()
809 }
810
811 fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
812 Ok(TypeId::MAP)
813 }
814
815 fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
816 Ok(TypeId::MAP)
817 }
818
819 fn fory_static_type_id() -> TypeId
820 where
821 Self: Sized,
822 {
823 TypeId::MAP
824 }
825
826 fn as_any(&self) -> &dyn std::any::Any {
827 self
828 }
829
830 fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
831 context.writer.write_u8(TypeId::MAP as u8);
832 Ok(())
833 }
834
835 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
836 read_basic_type_info::<Self>(context)
837 }
838}
839
840impl<K, V> ForyDefault for BTreeMap<K, V> {
841 fn fory_default() -> Self {
842 BTreeMap::new()
843 }
844}