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 const IS_POLYMORPHIC: bool = C::IS_POLYMORPHIC;
376
377 const IS_SHARED_REF: bool = true;
378
379 const IS_WRAPPER: bool = true;
380
381 const REQUIRES_SCOPED_ACCESS: bool = true;
382
383 #[inline(always)]
384 fn dynamic_type_id(value: &RcWeak<T>) -> Result<Option<std::any::TypeId>, Error> {
385 match value.upgrade() {
386 Some(value) => C::dynamic_type_id(&value),
387 None => Ok(None),
388 }
389 }
390}
391
392impl<T, C, const NULLABLE: bool, const TRACK_REF: bool> Codec<RcWeak<T>>
393 for RcWeakCodec<T, C, NULLABLE, TRACK_REF>
394where
395 T: 'static,
396 C: Codec<T>,
397{
398 #[inline(always)]
399 fn field_type(type_resolver: &TypeResolver) -> Result<FieldType, Error> {
400 let mut field_type = C::field_type(type_resolver)?;
401 field_type.nullable = NULLABLE;
402 field_type.track_ref = true;
403 Ok(field_type)
404 }
405
406 #[inline(always)]
407 fn write_field(value: &RcWeak<T>, context: &mut WriteContext) -> Result<(), Error> {
408 Self::write_with_mode(
409 value,
410 context,
411 RefMode::Tracking,
412 super::codec::codec_write_type_info::<T, C>(context),
413 true,
414 )
415 }
416
417 #[inline(always)]
418 fn read_field(context: &mut ReadContext) -> Result<RcWeak<T>, Error> {
419 <Self as Serializer>::read(
420 context,
421 RefMode::Tracking,
422 codec_read_type_info_static::<T, C>(context),
423 )
424 }
425
426 #[inline(always)]
427 fn read_field_with_type(
428 context: &mut ReadContext,
429 remote_field_type: &FieldType,
430 ) -> Result<RcWeak<T>, Error> {
431 read_rc_weak_with_type::<T, C>(context, RefMode::Tracking, remote_field_type)
432 }
433
434 #[inline(always)]
435 fn write_with_mode(
436 value: &RcWeak<T>,
437 context: &mut WriteContext,
438 ref_mode: RefMode,
439 write_type_info: bool,
440 has_generics: bool,
441 ) -> Result<(), Error> {
442 write_rc_weak_field::<T, C>(value, context, ref_mode, write_type_info, has_generics)
443 }
444
445 #[inline(always)]
446 fn write_with_type_info(
447 value: &RcWeak<T>,
448 context: &mut WriteContext,
449 ref_mode: RefMode,
450 type_info: &Rc<TypeInfo>,
451 has_generics: bool,
452 ) -> Result<(), Error> {
453 write_rc_weak_field_with_type_info::<T, C>(
454 value,
455 context,
456 ref_mode,
457 type_info,
458 has_generics,
459 )
460 }
461
462 #[inline(always)]
463 fn read_type_info_value(
464 context: &mut ReadContext,
465 ) -> Result<super::codec::CodecReadType, Error> {
466 C::read_type_info_value(context)
467 }
468}
469
470#[inline(always)]
471fn arc_weak_body<T: Send + Sync + 'static>(
472 value: &ArcWeak<T>,
473 context: &mut WriteContext,
474 ref_mode: RefMode,
475) -> Result<Option<Arc<T>>, Error> {
476 if !context.is_track_ref() {
477 return Err(arc_weak_tracking_error());
478 }
479 if ref_mode != RefMode::Tracking {
480 return Err(weak_write_mode_error("ArcWeak"));
481 }
482 let Some(value) = value.upgrade() else {
483 context.writer.write_i8(RefFlag::Null as i8);
484 return Ok(None);
485 };
486 if context
487 .ref_writer
488 .try_write_arc_ref(&mut context.writer, &value)
489 {
490 return Ok(None);
491 }
492 Ok(Some(value))
493}
494
495#[inline(always)]
496fn write_arc_weak<T: Send + Sync + 'static, C: Serializer<Target = T>>(
497 value: &ArcWeak<T>,
498 context: &mut WriteContext,
499 ref_mode: RefMode,
500 write_type_info: bool,
501) -> Result<(), Error> {
502 let Some(value) = arc_weak_body(value, context, ref_mode)? else {
503 return Ok(());
504 };
505 C::write(&value, context, RefMode::None, write_type_info)
506}
507
508#[inline(always)]
509fn write_arc_weak_field<T: Send + Sync + 'static, C: Codec<T>>(
510 value: &ArcWeak<T>,
511 context: &mut WriteContext,
512 ref_mode: RefMode,
513 write_type_info: bool,
514 has_generics: bool,
515) -> Result<(), Error> {
516 let Some(value) = arc_weak_body(value, context, ref_mode)? else {
517 return Ok(());
518 };
519 C::write_with_mode(
520 &value,
521 context,
522 RefMode::None,
523 write_type_info,
524 has_generics,
525 )
526}
527
528#[inline(always)]
529fn write_arc_weak_with_type_info<T: Send + Sync + 'static, C: Serializer<Target = T>>(
530 value: &ArcWeak<T>,
531 context: &mut WriteContext,
532 ref_mode: RefMode,
533 type_info: &Rc<TypeInfo>,
534) -> Result<(), Error> {
535 let Some(value) = arc_weak_body(value, context, ref_mode)? else {
536 return Ok(());
537 };
538 C::write_with_type_info(&value, context, RefMode::None, type_info)
539}
540
541#[inline(always)]
542fn write_arc_weak_field_with_type_info<T: Send + Sync + 'static, C: Codec<T>>(
543 value: &ArcWeak<T>,
544 context: &mut WriteContext,
545 ref_mode: RefMode,
546 type_info: &Rc<TypeInfo>,
547 has_generics: bool,
548) -> Result<(), Error> {
549 let Some(value) = arc_weak_body(value, context, ref_mode)? else {
550 return Ok(());
551 };
552 <C as Codec<T>>::write_with_type_info(&value, context, RefMode::None, type_info, has_generics)
553}
554
555#[inline(always)]
556fn read_arc_inner<T: Send + Sync + 'static, C: Serializer<Target = T>>(
557 context: &mut ReadContext,
558 read_type_info: bool,
559 type_info: Option<&Rc<TypeInfo>>,
560) -> Result<T, Error> {
561 reserve_strong::<T>(context)?;
562 if let Some(type_info) = type_info {
563 return C::read_with_type_info(context, RefMode::None, type_info);
564 }
565 C::read(context, RefMode::None, read_type_info)
568}
569
570#[inline(always)]
571fn read_arc_inner_with_type<T: Send + Sync + 'static, C: Codec<T>>(
572 context: &mut ReadContext,
573 remote_field_type: &FieldType,
574) -> Result<T, Error> {
575 reserve_strong::<T>(context)?;
576 if codec_read_type_info::<T, C>(context, remote_field_type) {
580 return C::read(context, RefMode::None, true);
581 }
582 C::read_data_with_type(context, remote_field_type)
583}
584
585macro_rules! read_arc_weak_owner {
586 ($context:ident, $ref_mode:expr, $read_inner:expr) => {{
587 if $ref_mode != RefMode::Tracking {
588 return Err(weak_read_mode_error("ArcWeak"));
589 }
590 match $context.ref_reader.read_ref_flag(&mut $context.reader)? {
591 RefFlag::Null => {
592 reserve_weak_cell::<std::sync::Weak<T>>($context)?;
593 Ok(ArcWeak::new())
594 }
595 RefFlag::RefValue => {
596 let ref_id = $context.ref_reader.reserve_ref_id();
600 $context.inc_depth()?;
601 let value = $read_inner?;
602 $context.dec_depth();
603 let strong = Arc::new(value);
604 reserve_weak_cell::<std::sync::Weak<T>>($context)?;
605 $context.ref_reader.store_arc_ref_at(ref_id, strong.clone());
606 Ok(ArcWeak::from(&strong))
607 }
608 RefFlag::Ref => {
609 let ref_id = $context.ref_reader.read_ref_id(&mut $context.reader)?;
610 reserve_weak_cell::<std::sync::Weak<T>>($context)?;
611 let weak = ArcWeak::new();
612 if let Some(strong) = $context.ref_reader.get_arc_ref::<T>(ref_id) {
613 weak.update(Arc::downgrade(&strong));
614 } else {
615 let callback_weak = weak.clone();
616 $context.ref_reader.add_callback(Box::new(move |reader| {
617 if let Some(strong) = reader.get_arc_ref::<T>(ref_id) {
618 callback_weak.update(Arc::downgrade(&strong));
619 }
620 }));
621 }
622 Ok(weak)
623 }
624 RefFlag::NotNullValue => Err(weak_untracked_value("ArcWeak")),
625 }
626 }};
627}
628
629#[inline(always)]
630fn read_arc_weak<T: Send + Sync + 'static, C: Serializer<Target = T>>(
631 context: &mut ReadContext,
632 ref_mode: RefMode,
633 read_type_info: bool,
634 type_info: Option<&Rc<TypeInfo>>,
635) -> Result<ArcWeak<T>, Error> {
636 read_arc_weak_owner!(
637 context,
638 ref_mode,
639 read_arc_inner::<T, C>(context, read_type_info, type_info)
640 )
641}
642
643#[inline(always)]
644fn read_arc_weak_with_type<T: Send + Sync + 'static, C: Codec<T>>(
645 context: &mut ReadContext,
646 ref_mode: RefMode,
647 remote_field_type: &FieldType,
648) -> Result<ArcWeak<T>, Error> {
649 read_arc_weak_owner!(
650 context,
651 ref_mode,
652 read_arc_inner_with_type::<T, C>(context, remote_field_type)
653 )
654}
655
656impl<T, C, const NULLABLE: bool, const TRACK_REF: bool> Serializer
657 for ArcWeakCodec<T, C, NULLABLE, TRACK_REF>
658where
659 T: Send + Sync + 'static,
660 C: Serializer<Target = T>,
661{
662 type Target = ArcWeak<T>;
663
664 #[inline(always)]
665 fn reserved_space() -> usize {
666 4
667 }
668
669 #[cold]
670 #[inline(never)]
671 fn write_data(_: &ArcWeak<T>, _: &mut WriteContext) -> Result<(), Error> {
672 Err(Error::not_allowed(
673 "ArcWeak must be written through its reference-tracking envelope",
674 ))
675 }
676
677 #[cold]
678 #[inline(never)]
679 fn read_data(_: &mut ReadContext) -> Result<ArcWeak<T>, Error> {
680 Err(Error::not_allowed(
681 "ArcWeak must be read through its reference-tracking envelope",
682 ))
683 }
684
685 #[inline(always)]
686 fn write(
687 value: &ArcWeak<T>,
688 context: &mut WriteContext,
689 ref_mode: RefMode,
690 write_type_info: bool,
691 ) -> Result<(), Error> {
692 write_arc_weak::<T, C>(value, context, ref_mode, write_type_info)
693 }
694
695 #[inline(always)]
696 fn write_type_info_value(
697 context: &mut WriteContext,
698 target_type_id: std::any::TypeId,
699 ) -> Result<Rc<TypeInfo>, Error> {
700 C::write_type_info_value(context, target_type_id)
701 }
702
703 #[inline(always)]
704 fn write_with_type_info(
705 value: &ArcWeak<T>,
706 context: &mut WriteContext,
707 ref_mode: RefMode,
708 type_info: &Rc<TypeInfo>,
709 ) -> Result<(), Error> {
710 write_arc_weak_with_type_info::<T, C>(value, context, ref_mode, type_info)
711 }
712
713 #[inline(always)]
714 fn read(
715 context: &mut ReadContext,
716 ref_mode: RefMode,
717 read_type_info: bool,
718 ) -> Result<ArcWeak<T>, Error> {
719 read_arc_weak::<T, C>(context, ref_mode, read_type_info, None)
720 }
721
722 #[inline(always)]
723 fn read_with_type_info(
724 context: &mut ReadContext,
725 ref_mode: RefMode,
726 type_info: &Rc<TypeInfo>,
727 ) -> Result<ArcWeak<T>, Error> {
728 read_arc_weak::<T, C>(context, ref_mode, false, Some(type_info))
729 }
730
731 #[inline(always)]
732 fn default_value(context: &mut ReadContext) -> Result<ArcWeak<T>, Error> {
733 reserve_weak_cell::<std::sync::Weak<T>>(context)?;
734 Ok(ArcWeak::new())
735 }
736
737 #[inline(always)]
738 fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
739 C::write_type_info(context)
740 }
741
742 #[inline(always)]
743 fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
744 C::read_type_info(context)
745 }
746
747 #[inline(always)]
748 fn static_type_id() -> TypeId {
749 C::static_type_id()
750 }
751
752 const IS_POLYMORPHIC: bool = C::IS_POLYMORPHIC;
753
754 const IS_SHARED_REF: bool = true;
755
756 const IS_WRAPPER: bool = true;
757
758 const REQUIRES_SCOPED_ACCESS: bool = true;
759
760 #[inline(always)]
761 fn dynamic_type_id(value: &ArcWeak<T>) -> Result<Option<std::any::TypeId>, Error> {
762 match value.upgrade() {
763 Some(value) => C::dynamic_type_id(&value),
764 None => Ok(None),
765 }
766 }
767}
768
769impl<T, C, const NULLABLE: bool, const TRACK_REF: bool> Codec<ArcWeak<T>>
770 for ArcWeakCodec<T, C, NULLABLE, TRACK_REF>
771where
772 T: Send + Sync + 'static,
773 C: Codec<T>,
774{
775 #[inline(always)]
776 fn field_type(type_resolver: &TypeResolver) -> Result<FieldType, Error> {
777 let mut field_type = C::field_type(type_resolver)?;
778 field_type.nullable = NULLABLE;
779 field_type.track_ref = true;
780 Ok(field_type)
781 }
782
783 #[inline(always)]
784 fn write_field(value: &ArcWeak<T>, context: &mut WriteContext) -> Result<(), Error> {
785 Self::write_with_mode(
786 value,
787 context,
788 RefMode::Tracking,
789 super::codec::codec_write_type_info::<T, C>(context),
790 true,
791 )
792 }
793
794 #[inline(always)]
795 fn read_field(context: &mut ReadContext) -> Result<ArcWeak<T>, Error> {
796 <Self as Serializer>::read(
797 context,
798 RefMode::Tracking,
799 codec_read_type_info_static::<T, C>(context),
800 )
801 }
802
803 #[inline(always)]
804 fn read_field_with_type(
805 context: &mut ReadContext,
806 remote_field_type: &FieldType,
807 ) -> Result<ArcWeak<T>, Error> {
808 read_arc_weak_with_type::<T, C>(context, RefMode::Tracking, remote_field_type)
809 }
810
811 #[inline(always)]
812 fn write_with_mode(
813 value: &ArcWeak<T>,
814 context: &mut WriteContext,
815 ref_mode: RefMode,
816 write_type_info: bool,
817 has_generics: bool,
818 ) -> Result<(), Error> {
819 write_arc_weak_field::<T, C>(value, context, ref_mode, write_type_info, has_generics)
820 }
821
822 #[inline(always)]
823 fn write_with_type_info(
824 value: &ArcWeak<T>,
825 context: &mut WriteContext,
826 ref_mode: RefMode,
827 type_info: &Rc<TypeInfo>,
828 has_generics: bool,
829 ) -> Result<(), Error> {
830 write_arc_weak_field_with_type_info::<T, C>(
831 value,
832 context,
833 ref_mode,
834 type_info,
835 has_generics,
836 )
837 }
838
839 #[inline(always)]
840 fn read_type_info_value(
841 context: &mut ReadContext,
842 ) -> Result<super::codec::CodecReadType, Error> {
843 C::read_type_info_value(context)
844 }
845}
846
847impl_single_carrier_serializer!(RcWeakSerializer, RcWeak, RcWeakCodec, wrapper = true);
848
849impl_single_carrier_serializer!(
850 ArcWeakSerializer,
851 ArcWeak,
852 ArcWeakCodec,
853 wrapper = true,
854 bounds = [Send + Sync]
855);