1use super::codec::{codec_read_type_info, codec_read_type_info_static, Codec};
21use crate::context::{ReadContext, WriteContext};
22use crate::error::Error;
23use crate::meta::FieldType;
24use crate::resolver::{RefFlag, RefMode, TypeInfo, TypeResolver};
25use crate::serializer::Serializer;
26use crate::type_id::TypeId;
27use crate::types::{ArcWeak, RcWeak};
28use std::marker::PhantomData;
29use std::rc::Rc;
30use std::sync::Arc;
31
32pub struct RcWeakCodec<T, C, const NULLABLE: bool, const TRACK_REF: bool>(PhantomData<(T, C)>);
33
34pub struct ArcWeakCodec<T, C, const NULLABLE: bool, const TRACK_REF: bool>(PhantomData<(T, C)>);
35
36#[inline(always)]
37fn reserve_weak_cell<W>(context: &mut ReadContext) -> Result<(), Error> {
38 let bytes = std::mem::size_of::<W>();
39 if bytes != 0 {
40 context.reserve_graph_memory(bytes)?;
41 }
42 Ok(())
43}
44
45#[inline(always)]
46fn reserve_strong<T>(context: &mut ReadContext) -> Result<(), Error> {
47 let bytes = std::mem::size_of::<T>();
48 if bytes != 0 {
49 context.reserve_graph_memory(bytes)?;
50 }
51 Ok(())
52}
53
54#[cold]
55#[inline(never)]
56fn rc_weak_tracking_error() -> Error {
57 Error::invalid_ref(
58 "RcWeak requires track_ref to be enabled. \
59 Use Fory::builder().track_ref(true).build()",
60 )
61}
62
63#[cold]
64#[inline(never)]
65fn arc_weak_tracking_error() -> Error {
66 Error::invalid_ref(
67 "ArcWeak requires track_ref to be enabled. \
68 Use Fory::builder().track_ref(true).build()",
69 )
70}
71
72#[cold]
73#[inline(never)]
74fn weak_write_mode_error(owner: &str) -> Error {
75 Error::invalid_ref(format!(
76 "{owner} requires RefMode::Tracking for serialization"
77 ))
78}
79
80#[cold]
81#[inline(never)]
82fn weak_read_mode_error(owner: &str) -> Error {
83 Error::invalid_ref(format!(
84 "{owner} requires RefMode::Tracking for deserialization"
85 ))
86}
87
88#[cold]
89#[inline(never)]
90fn weak_untracked_value(owner: &str) -> Error {
91 Error::invalid_ref(format!("{owner} cannot contain an untracked strong value"))
92}
93
94#[inline(always)]
95fn rc_weak_body<T: 'static>(
96 value: &RcWeak<T>,
97 context: &mut WriteContext,
98 ref_mode: RefMode,
99) -> Result<Option<Rc<T>>, Error> {
100 if !context.is_track_ref() {
101 return Err(rc_weak_tracking_error());
102 }
103 if ref_mode != RefMode::Tracking {
104 return Err(weak_write_mode_error("RcWeak"));
105 }
106 let Some(value) = value.upgrade() else {
107 context.writer.write_i8(RefFlag::Null as i8);
108 return Ok(None);
109 };
110 if context
111 .ref_writer
112 .try_write_rc_ref(&mut context.writer, &value)
113 {
114 return Ok(None);
115 }
116 Ok(Some(value))
117}
118
119#[inline(always)]
120fn write_rc_weak<T: 'static, C: Serializer<Target = T>>(
121 value: &RcWeak<T>,
122 context: &mut WriteContext,
123 ref_mode: RefMode,
124 write_type_info: bool,
125) -> Result<(), Error> {
126 let Some(value) = rc_weak_body(value, context, ref_mode)? else {
127 return Ok(());
128 };
129 C::write(&value, context, RefMode::None, write_type_info)
130}
131
132#[inline(always)]
133fn write_rc_weak_field<T: 'static, C: Codec<T>>(
134 value: &RcWeak<T>,
135 context: &mut WriteContext,
136 ref_mode: RefMode,
137 write_type_info: bool,
138 has_generics: bool,
139) -> Result<(), Error> {
140 let Some(value) = rc_weak_body(value, context, ref_mode)? else {
141 return Ok(());
142 };
143 C::write_with_mode(
144 &value,
145 context,
146 RefMode::None,
147 write_type_info,
148 has_generics,
149 )
150}
151
152#[inline(always)]
153fn write_rc_weak_with_type_info<T: 'static, C: Serializer<Target = T>>(
154 value: &RcWeak<T>,
155 context: &mut WriteContext,
156 ref_mode: RefMode,
157 type_info: &Rc<TypeInfo>,
158) -> Result<(), Error> {
159 let Some(value) = rc_weak_body(value, context, ref_mode)? else {
160 return Ok(());
161 };
162 C::write_with_type_info(&value, context, RefMode::None, type_info)
163}
164
165#[inline(always)]
166fn write_rc_weak_field_with_type_info<T: 'static, C: Codec<T>>(
167 value: &RcWeak<T>,
168 context: &mut WriteContext,
169 ref_mode: RefMode,
170 type_info: &Rc<TypeInfo>,
171 has_generics: bool,
172) -> Result<(), Error> {
173 let Some(value) = rc_weak_body(value, context, ref_mode)? else {
174 return Ok(());
175 };
176 <C as Codec<T>>::write_with_type_info(&value, context, RefMode::None, type_info, has_generics)
177}
178
179#[inline(always)]
180fn read_rc_inner<T: 'static, C: Serializer<Target = T>>(
181 context: &mut ReadContext,
182 read_type_info: bool,
183 type_info: Option<&Rc<TypeInfo>>,
184) -> Result<T, Error> {
185 reserve_strong::<T>(context)?;
186 if let Some(type_info) = type_info {
187 return C::read_with_type_info(context, RefMode::None, type_info);
188 }
189 C::read(context, RefMode::None, read_type_info)
192}
193
194#[inline(always)]
195fn read_rc_inner_with_type<T: 'static, C: Codec<T>>(
196 context: &mut ReadContext,
197 remote_field_type: &FieldType,
198) -> Result<T, Error> {
199 reserve_strong::<T>(context)?;
200 if codec_read_type_info::<T, C>(context, remote_field_type) {
204 return C::read(context, RefMode::None, true);
205 }
206 C::read_data_with_type(context, remote_field_type)
207}
208
209macro_rules! read_rc_weak_owner {
210 ($context:ident, $ref_mode:expr, $read_inner:expr) => {{
211 if $ref_mode != RefMode::Tracking {
212 return Err(weak_read_mode_error("RcWeak"));
213 }
214 match $context.ref_reader.read_ref_flag(&mut $context.reader)? {
215 RefFlag::Null => {
216 reserve_weak_cell::<std::rc::Weak<T>>($context)?;
217 Ok(RcWeak::new())
218 }
219 RefFlag::RefValue => {
220 let ref_id = $context.ref_reader.reserve_ref_id();
224 $context.inc_depth()?;
225 let value = $read_inner?;
226 $context.dec_depth();
227 let strong = Rc::new(value);
228 reserve_weak_cell::<std::rc::Weak<T>>($context)?;
229 $context.ref_reader.store_rc_ref_at(ref_id, strong.clone());
230 Ok(RcWeak::from(&strong))
231 }
232 RefFlag::Ref => {
233 let ref_id = $context.ref_reader.read_ref_id(&mut $context.reader)?;
234 reserve_weak_cell::<std::rc::Weak<T>>($context)?;
235 if let Some(strong) = $context.ref_reader.get_rc_ref::<T>(ref_id) {
236 return Ok(RcWeak::from(&strong));
237 }
238 let weak = RcWeak::new();
239 let callback_weak = weak.clone();
240 $context.ref_reader.add_callback(Box::new(move |reader| {
241 if let Some(strong) = reader.get_rc_ref::<T>(ref_id) {
242 callback_weak.update(Rc::downgrade(&strong));
243 }
244 }));
245 Ok(weak)
246 }
247 RefFlag::NotNullValue => Err(weak_untracked_value("RcWeak")),
248 }
249 }};
250}
251
252#[inline(always)]
253fn read_rc_weak<T: 'static, C: Serializer<Target = T>>(
254 context: &mut ReadContext,
255 ref_mode: RefMode,
256 read_type_info: bool,
257 type_info: Option<&Rc<TypeInfo>>,
258) -> Result<RcWeak<T>, Error> {
259 read_rc_weak_owner!(
260 context,
261 ref_mode,
262 read_rc_inner::<T, C>(context, read_type_info, type_info)
263 )
264}
265
266#[inline(always)]
267fn read_rc_weak_with_type<T: 'static, C: Codec<T>>(
268 context: &mut ReadContext,
269 ref_mode: RefMode,
270 remote_field_type: &FieldType,
271) -> Result<RcWeak<T>, Error> {
272 read_rc_weak_owner!(
273 context,
274 ref_mode,
275 read_rc_inner_with_type::<T, C>(context, remote_field_type)
276 )
277}
278
279impl<T, C, const NULLABLE: bool, const TRACK_REF: bool> Serializer
280 for RcWeakCodec<T, C, NULLABLE, TRACK_REF>
281where
282 T: 'static,
283 C: Serializer<Target = T>,
284{
285 type Target = RcWeak<T>;
286
287 #[inline(always)]
288 fn reserved_space() -> usize {
289 4
290 }
291
292 #[cold]
293 #[inline(never)]
294 fn write_data(_: &RcWeak<T>, _: &mut WriteContext) -> Result<(), Error> {
295 Err(Error::not_allowed(
296 "RcWeak must be written through its reference-tracking envelope",
297 ))
298 }
299
300 #[cold]
301 #[inline(never)]
302 fn read_data(_: &mut ReadContext) -> Result<RcWeak<T>, Error> {
303 Err(Error::not_allowed(
304 "RcWeak must be read through its reference-tracking envelope",
305 ))
306 }
307
308 #[inline(always)]
309 fn write(
310 value: &RcWeak<T>,
311 context: &mut WriteContext,
312 ref_mode: RefMode,
313 write_type_info: bool,
314 ) -> Result<(), Error> {
315 write_rc_weak::<T, C>(value, context, ref_mode, write_type_info)
316 }
317
318 #[inline(always)]
319 fn write_type_info_value(
320 context: &mut WriteContext,
321 target_type_id: std::any::TypeId,
322 ) -> Result<Rc<TypeInfo>, Error> {
323 C::write_type_info_value(context, target_type_id)
324 }
325
326 #[inline(always)]
327 fn write_with_type_info(
328 value: &RcWeak<T>,
329 context: &mut WriteContext,
330 ref_mode: RefMode,
331 type_info: &Rc<TypeInfo>,
332 ) -> Result<(), Error> {
333 write_rc_weak_with_type_info::<T, C>(value, context, ref_mode, type_info)
334 }
335
336 #[inline(always)]
337 fn read(
338 context: &mut ReadContext,
339 ref_mode: RefMode,
340 read_type_info: bool,
341 ) -> Result<RcWeak<T>, Error> {
342 read_rc_weak::<T, C>(context, ref_mode, read_type_info, None)
343 }
344
345 #[inline(always)]
346 fn read_with_type_info(
347 context: &mut ReadContext,
348 ref_mode: RefMode,
349 type_info: &Rc<TypeInfo>,
350 ) -> Result<RcWeak<T>, Error> {
351 read_rc_weak::<T, C>(context, ref_mode, false, Some(type_info))
352 }
353
354 #[inline(always)]
355 fn default_value(context: &mut ReadContext) -> Result<RcWeak<T>, Error> {
356 reserve_weak_cell::<std::rc::Weak<T>>(context)?;
357 Ok(RcWeak::new())
358 }
359
360 #[inline(always)]
361 fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
362 C::write_type_info(context)
363 }
364
365 #[inline(always)]
366 fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
367 C::read_type_info(context)
368 }
369
370 #[inline(always)]
371 fn static_type_id() -> TypeId {
372 C::static_type_id()
373 }
374
375 #[inline(always)]
376 fn metadata_target_type_id() -> std::any::TypeId {
377 C::metadata_target_type_id()
378 }
379
380 const IS_POLYMORPHIC: bool = C::IS_POLYMORPHIC;
381
382 const IS_SHARED_REF: bool = true;
383
384 const IS_WRAPPER: bool = true;
385
386 const REQUIRES_SCOPED_ACCESS: bool = true;
387
388 #[inline(always)]
389 fn dynamic_type_id(value: &RcWeak<T>) -> Result<Option<std::any::TypeId>, Error> {
390 match value.upgrade() {
391 Some(value) => C::dynamic_type_id(&value),
392 None => Ok(None),
393 }
394 }
395}
396
397impl<T, C, const NULLABLE: bool, const TRACK_REF: bool> Codec<RcWeak<T>>
398 for RcWeakCodec<T, C, NULLABLE, TRACK_REF>
399where
400 T: 'static,
401 C: Codec<T>,
402{
403 #[inline(always)]
404 fn field_type(type_resolver: &TypeResolver) -> Result<FieldType, Error> {
405 let mut field_type = C::field_type(type_resolver)?;
406 field_type.nullable = NULLABLE;
407 field_type.track_ref = true;
408 Ok(field_type)
409 }
410
411 #[inline(always)]
412 fn write_field(value: &RcWeak<T>, context: &mut WriteContext) -> Result<(), Error> {
413 Self::write_with_mode(
414 value,
415 context,
416 RefMode::Tracking,
417 super::codec::codec_write_type_info::<T, C>(context),
418 true,
419 )
420 }
421
422 #[inline(always)]
423 fn read_field(context: &mut ReadContext) -> Result<RcWeak<T>, Error> {
424 <Self as Serializer>::read(
425 context,
426 RefMode::Tracking,
427 codec_read_type_info_static::<T, C>(context),
428 )
429 }
430
431 #[inline(always)]
432 fn read_field_with_type(
433 context: &mut ReadContext,
434 remote_field_type: &FieldType,
435 ) -> Result<RcWeak<T>, Error> {
436 read_rc_weak_with_type::<T, C>(context, RefMode::Tracking, remote_field_type)
437 }
438
439 #[inline(always)]
440 fn write_with_mode(
441 value: &RcWeak<T>,
442 context: &mut WriteContext,
443 ref_mode: RefMode,
444 write_type_info: bool,
445 has_generics: bool,
446 ) -> Result<(), Error> {
447 write_rc_weak_field::<T, C>(value, context, ref_mode, write_type_info, has_generics)
448 }
449
450 #[inline(always)]
451 fn write_with_type_info(
452 value: &RcWeak<T>,
453 context: &mut WriteContext,
454 ref_mode: RefMode,
455 type_info: &Rc<TypeInfo>,
456 has_generics: bool,
457 ) -> Result<(), Error> {
458 write_rc_weak_field_with_type_info::<T, C>(
459 value,
460 context,
461 ref_mode,
462 type_info,
463 has_generics,
464 )
465 }
466
467 #[inline(always)]
468 fn read_type_info_value(
469 context: &mut ReadContext,
470 ) -> Result<super::codec::CodecReadType, Error> {
471 C::read_type_info_value(context)
472 }
473}
474
475#[inline(always)]
476fn arc_weak_body<T: Send + Sync + 'static>(
477 value: &ArcWeak<T>,
478 context: &mut WriteContext,
479 ref_mode: RefMode,
480) -> Result<Option<Arc<T>>, Error> {
481 if !context.is_track_ref() {
482 return Err(arc_weak_tracking_error());
483 }
484 if ref_mode != RefMode::Tracking {
485 return Err(weak_write_mode_error("ArcWeak"));
486 }
487 let Some(value) = value.upgrade() else {
488 context.writer.write_i8(RefFlag::Null as i8);
489 return Ok(None);
490 };
491 if context
492 .ref_writer
493 .try_write_arc_ref(&mut context.writer, &value)
494 {
495 return Ok(None);
496 }
497 Ok(Some(value))
498}
499
500#[inline(always)]
501fn write_arc_weak<T: Send + Sync + 'static, C: Serializer<Target = T>>(
502 value: &ArcWeak<T>,
503 context: &mut WriteContext,
504 ref_mode: RefMode,
505 write_type_info: bool,
506) -> Result<(), Error> {
507 let Some(value) = arc_weak_body(value, context, ref_mode)? else {
508 return Ok(());
509 };
510 C::write(&value, context, RefMode::None, write_type_info)
511}
512
513#[inline(always)]
514fn write_arc_weak_field<T: Send + Sync + 'static, C: Codec<T>>(
515 value: &ArcWeak<T>,
516 context: &mut WriteContext,
517 ref_mode: RefMode,
518 write_type_info: bool,
519 has_generics: bool,
520) -> Result<(), Error> {
521 let Some(value) = arc_weak_body(value, context, ref_mode)? else {
522 return Ok(());
523 };
524 C::write_with_mode(
525 &value,
526 context,
527 RefMode::None,
528 write_type_info,
529 has_generics,
530 )
531}
532
533#[inline(always)]
534fn write_arc_weak_with_type_info<T: Send + Sync + 'static, C: Serializer<Target = T>>(
535 value: &ArcWeak<T>,
536 context: &mut WriteContext,
537 ref_mode: RefMode,
538 type_info: &Rc<TypeInfo>,
539) -> Result<(), Error> {
540 let Some(value) = arc_weak_body(value, context, ref_mode)? else {
541 return Ok(());
542 };
543 C::write_with_type_info(&value, context, RefMode::None, type_info)
544}
545
546#[inline(always)]
547fn write_arc_weak_field_with_type_info<T: Send + Sync + 'static, C: Codec<T>>(
548 value: &ArcWeak<T>,
549 context: &mut WriteContext,
550 ref_mode: RefMode,
551 type_info: &Rc<TypeInfo>,
552 has_generics: bool,
553) -> Result<(), Error> {
554 let Some(value) = arc_weak_body(value, context, ref_mode)? else {
555 return Ok(());
556 };
557 <C as Codec<T>>::write_with_type_info(&value, context, RefMode::None, type_info, has_generics)
558}
559
560#[inline(always)]
561fn read_arc_inner<T: Send + Sync + 'static, C: Serializer<Target = T>>(
562 context: &mut ReadContext,
563 read_type_info: bool,
564 type_info: Option<&Rc<TypeInfo>>,
565) -> Result<T, Error> {
566 reserve_strong::<T>(context)?;
567 if let Some(type_info) = type_info {
568 return C::read_with_type_info(context, RefMode::None, type_info);
569 }
570 C::read(context, RefMode::None, read_type_info)
573}
574
575#[inline(always)]
576fn read_arc_inner_with_type<T: Send + Sync + 'static, C: Codec<T>>(
577 context: &mut ReadContext,
578 remote_field_type: &FieldType,
579) -> Result<T, Error> {
580 reserve_strong::<T>(context)?;
581 if codec_read_type_info::<T, C>(context, remote_field_type) {
585 return C::read(context, RefMode::None, true);
586 }
587 C::read_data_with_type(context, remote_field_type)
588}
589
590macro_rules! read_arc_weak_owner {
591 ($context:ident, $ref_mode:expr, $read_inner:expr) => {{
592 if $ref_mode != RefMode::Tracking {
593 return Err(weak_read_mode_error("ArcWeak"));
594 }
595 match $context.ref_reader.read_ref_flag(&mut $context.reader)? {
596 RefFlag::Null => {
597 reserve_weak_cell::<std::sync::Weak<T>>($context)?;
598 Ok(ArcWeak::new())
599 }
600 RefFlag::RefValue => {
601 let ref_id = $context.ref_reader.reserve_ref_id();
605 $context.inc_depth()?;
606 let value = $read_inner?;
607 $context.dec_depth();
608 let strong = Arc::new(value);
609 reserve_weak_cell::<std::sync::Weak<T>>($context)?;
610 $context.ref_reader.store_arc_ref_at(ref_id, strong.clone());
611 Ok(ArcWeak::from(&strong))
612 }
613 RefFlag::Ref => {
614 let ref_id = $context.ref_reader.read_ref_id(&mut $context.reader)?;
615 reserve_weak_cell::<std::sync::Weak<T>>($context)?;
616 let weak = ArcWeak::new();
617 if let Some(strong) = $context.ref_reader.get_arc_ref::<T>(ref_id) {
618 weak.update(Arc::downgrade(&strong));
619 } else {
620 let callback_weak = weak.clone();
621 $context.ref_reader.add_callback(Box::new(move |reader| {
622 if let Some(strong) = reader.get_arc_ref::<T>(ref_id) {
623 callback_weak.update(Arc::downgrade(&strong));
624 }
625 }));
626 }
627 Ok(weak)
628 }
629 RefFlag::NotNullValue => Err(weak_untracked_value("ArcWeak")),
630 }
631 }};
632}
633
634#[inline(always)]
635fn read_arc_weak<T: Send + Sync + 'static, C: Serializer<Target = T>>(
636 context: &mut ReadContext,
637 ref_mode: RefMode,
638 read_type_info: bool,
639 type_info: Option<&Rc<TypeInfo>>,
640) -> Result<ArcWeak<T>, Error> {
641 read_arc_weak_owner!(
642 context,
643 ref_mode,
644 read_arc_inner::<T, C>(context, read_type_info, type_info)
645 )
646}
647
648#[inline(always)]
649fn read_arc_weak_with_type<T: Send + Sync + 'static, C: Codec<T>>(
650 context: &mut ReadContext,
651 ref_mode: RefMode,
652 remote_field_type: &FieldType,
653) -> Result<ArcWeak<T>, Error> {
654 read_arc_weak_owner!(
655 context,
656 ref_mode,
657 read_arc_inner_with_type::<T, C>(context, remote_field_type)
658 )
659}
660
661impl<T, C, const NULLABLE: bool, const TRACK_REF: bool> Serializer
662 for ArcWeakCodec<T, C, NULLABLE, TRACK_REF>
663where
664 T: Send + Sync + 'static,
665 C: Serializer<Target = T>,
666{
667 type Target = ArcWeak<T>;
668
669 #[inline(always)]
670 fn reserved_space() -> usize {
671 4
672 }
673
674 #[cold]
675 #[inline(never)]
676 fn write_data(_: &ArcWeak<T>, _: &mut WriteContext) -> Result<(), Error> {
677 Err(Error::not_allowed(
678 "ArcWeak must be written through its reference-tracking envelope",
679 ))
680 }
681
682 #[cold]
683 #[inline(never)]
684 fn read_data(_: &mut ReadContext) -> Result<ArcWeak<T>, Error> {
685 Err(Error::not_allowed(
686 "ArcWeak must be read through its reference-tracking envelope",
687 ))
688 }
689
690 #[inline(always)]
691 fn write(
692 value: &ArcWeak<T>,
693 context: &mut WriteContext,
694 ref_mode: RefMode,
695 write_type_info: bool,
696 ) -> Result<(), Error> {
697 write_arc_weak::<T, C>(value, context, ref_mode, write_type_info)
698 }
699
700 #[inline(always)]
701 fn write_type_info_value(
702 context: &mut WriteContext,
703 target_type_id: std::any::TypeId,
704 ) -> Result<Rc<TypeInfo>, Error> {
705 C::write_type_info_value(context, target_type_id)
706 }
707
708 #[inline(always)]
709 fn write_with_type_info(
710 value: &ArcWeak<T>,
711 context: &mut WriteContext,
712 ref_mode: RefMode,
713 type_info: &Rc<TypeInfo>,
714 ) -> Result<(), Error> {
715 write_arc_weak_with_type_info::<T, C>(value, context, ref_mode, type_info)
716 }
717
718 #[inline(always)]
719 fn read(
720 context: &mut ReadContext,
721 ref_mode: RefMode,
722 read_type_info: bool,
723 ) -> Result<ArcWeak<T>, Error> {
724 read_arc_weak::<T, C>(context, ref_mode, read_type_info, None)
725 }
726
727 #[inline(always)]
728 fn read_with_type_info(
729 context: &mut ReadContext,
730 ref_mode: RefMode,
731 type_info: &Rc<TypeInfo>,
732 ) -> Result<ArcWeak<T>, Error> {
733 read_arc_weak::<T, C>(context, ref_mode, false, Some(type_info))
734 }
735
736 #[inline(always)]
737 fn default_value(context: &mut ReadContext) -> Result<ArcWeak<T>, Error> {
738 reserve_weak_cell::<std::sync::Weak<T>>(context)?;
739 Ok(ArcWeak::new())
740 }
741
742 #[inline(always)]
743 fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
744 C::write_type_info(context)
745 }
746
747 #[inline(always)]
748 fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
749 C::read_type_info(context)
750 }
751
752 #[inline(always)]
753 fn static_type_id() -> TypeId {
754 C::static_type_id()
755 }
756
757 #[inline(always)]
758 fn metadata_target_type_id() -> std::any::TypeId {
759 C::metadata_target_type_id()
760 }
761
762 const IS_POLYMORPHIC: bool = C::IS_POLYMORPHIC;
763
764 const IS_SHARED_REF: bool = true;
765
766 const IS_WRAPPER: bool = true;
767
768 const REQUIRES_SCOPED_ACCESS: bool = true;
769
770 #[inline(always)]
771 fn dynamic_type_id(value: &ArcWeak<T>) -> Result<Option<std::any::TypeId>, Error> {
772 match value.upgrade() {
773 Some(value) => C::dynamic_type_id(&value),
774 None => Ok(None),
775 }
776 }
777}
778
779impl<T, C, const NULLABLE: bool, const TRACK_REF: bool> Codec<ArcWeak<T>>
780 for ArcWeakCodec<T, C, NULLABLE, TRACK_REF>
781where
782 T: Send + Sync + 'static,
783 C: Codec<T>,
784{
785 #[inline(always)]
786 fn field_type(type_resolver: &TypeResolver) -> Result<FieldType, Error> {
787 let mut field_type = C::field_type(type_resolver)?;
788 field_type.nullable = NULLABLE;
789 field_type.track_ref = true;
790 Ok(field_type)
791 }
792
793 #[inline(always)]
794 fn write_field(value: &ArcWeak<T>, context: &mut WriteContext) -> Result<(), Error> {
795 Self::write_with_mode(
796 value,
797 context,
798 RefMode::Tracking,
799 super::codec::codec_write_type_info::<T, C>(context),
800 true,
801 )
802 }
803
804 #[inline(always)]
805 fn read_field(context: &mut ReadContext) -> Result<ArcWeak<T>, Error> {
806 <Self as Serializer>::read(
807 context,
808 RefMode::Tracking,
809 codec_read_type_info_static::<T, C>(context),
810 )
811 }
812
813 #[inline(always)]
814 fn read_field_with_type(
815 context: &mut ReadContext,
816 remote_field_type: &FieldType,
817 ) -> Result<ArcWeak<T>, Error> {
818 read_arc_weak_with_type::<T, C>(context, RefMode::Tracking, remote_field_type)
819 }
820
821 #[inline(always)]
822 fn write_with_mode(
823 value: &ArcWeak<T>,
824 context: &mut WriteContext,
825 ref_mode: RefMode,
826 write_type_info: bool,
827 has_generics: bool,
828 ) -> Result<(), Error> {
829 write_arc_weak_field::<T, C>(value, context, ref_mode, write_type_info, has_generics)
830 }
831
832 #[inline(always)]
833 fn write_with_type_info(
834 value: &ArcWeak<T>,
835 context: &mut WriteContext,
836 ref_mode: RefMode,
837 type_info: &Rc<TypeInfo>,
838 has_generics: bool,
839 ) -> Result<(), Error> {
840 write_arc_weak_field_with_type_info::<T, C>(
841 value,
842 context,
843 ref_mode,
844 type_info,
845 has_generics,
846 )
847 }
848
849 #[inline(always)]
850 fn read_type_info_value(
851 context: &mut ReadContext,
852 ) -> Result<super::codec::CodecReadType, Error> {
853 C::read_type_info_value(context)
854 }
855}
856
857impl_single_carrier_serializer!(RcWeakSerializer, RcWeak, RcWeakCodec, wrapper = true);
858
859impl_single_carrier_serializer!(
860 ArcWeakSerializer,
861 ArcWeak,
862 ArcWeakCodec,
863 wrapper = true,
864 bounds = [Send + Sync]
865);