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