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