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_ref_missing_after_insert(owner: &str, ref_id: u32) -> Error {
75 Error::invalid_ref(format!(
76 "{owner} reference {ref_id} not found after insertion"
77 ))
78}
79
80#[cold]
81#[inline(never)]
82fn weak_write_mode_error(owner: &str) -> Error {
83 Error::invalid_ref(format!(
84 "{owner} requires RefMode::Tracking for serialization"
85 ))
86}
87
88#[cold]
89#[inline(never)]
90fn weak_read_mode_error(owner: &str) -> Error {
91 Error::invalid_ref(format!(
92 "{owner} requires RefMode::Tracking for deserialization"
93 ))
94}
95
96#[cold]
97#[inline(never)]
98fn weak_untracked_value(owner: &str) -> Error {
99 Error::invalid_ref(format!("{owner} cannot contain an untracked strong value"))
100}
101
102#[inline(always)]
103fn rc_weak_body<T: 'static>(
104 value: &RcWeak<T>,
105 context: &mut WriteContext,
106 ref_mode: RefMode,
107) -> Result<Option<Rc<T>>, Error> {
108 if !context.is_track_ref() {
109 return Err(rc_weak_tracking_error());
110 }
111 if ref_mode != RefMode::Tracking {
112 return Err(weak_write_mode_error("RcWeak"));
113 }
114 let Some(value) = value.upgrade() else {
115 context.writer.write_i8(RefFlag::Null as i8);
116 return Ok(None);
117 };
118 if context
119 .ref_writer
120 .try_write_rc_ref(&mut context.writer, &value)
121 {
122 return Ok(None);
123 }
124 Ok(Some(value))
125}
126
127#[inline(always)]
128fn write_rc_weak<T: 'static, C: Serializer<Target = T>>(
129 value: &RcWeak<T>,
130 context: &mut WriteContext,
131 ref_mode: RefMode,
132 write_type_info: bool,
133) -> Result<(), Error> {
134 let Some(value) = rc_weak_body(value, context, ref_mode)? else {
135 return Ok(());
136 };
137 C::write(&value, context, RefMode::None, write_type_info)
138}
139
140#[inline(always)]
141fn write_rc_weak_field<T: 'static, C: Codec<T>>(
142 value: &RcWeak<T>,
143 context: &mut WriteContext,
144 ref_mode: RefMode,
145 write_type_info: bool,
146 has_generics: bool,
147) -> Result<(), Error> {
148 let Some(value) = rc_weak_body(value, context, ref_mode)? else {
149 return Ok(());
150 };
151 C::write_with_mode(
152 &value,
153 context,
154 RefMode::None,
155 write_type_info,
156 has_generics,
157 )
158}
159
160#[inline(always)]
161fn write_rc_weak_with_type_info<T: 'static, C: Serializer<Target = T>>(
162 value: &RcWeak<T>,
163 context: &mut WriteContext,
164 ref_mode: RefMode,
165 type_info: &Rc<TypeInfo>,
166) -> Result<(), Error> {
167 let Some(value) = rc_weak_body(value, context, ref_mode)? else {
168 return Ok(());
169 };
170 C::write_with_type_info(&value, context, RefMode::None, type_info)
171}
172
173#[inline(always)]
174fn write_rc_weak_field_with_type_info<T: 'static, C: Codec<T>>(
175 value: &RcWeak<T>,
176 context: &mut WriteContext,
177 ref_mode: RefMode,
178 type_info: &Rc<TypeInfo>,
179 has_generics: bool,
180) -> Result<(), Error> {
181 let Some(value) = rc_weak_body(value, context, ref_mode)? else {
182 return Ok(());
183 };
184 <C as Codec<T>>::write_with_type_info(&value, context, RefMode::None, type_info, has_generics)
185}
186
187#[inline(always)]
188fn read_rc_inner<T: 'static, C: Serializer<Target = T>>(
189 context: &mut ReadContext,
190 read_type_info: bool,
191 type_info: Option<&Rc<TypeInfo>>,
192) -> Result<T, Error> {
193 reserve_strong::<T>(context)?;
194 if let Some(type_info) = type_info {
195 return C::read_with_type_info(context, RefMode::None, type_info);
196 }
197 C::read(context, RefMode::None, read_type_info)
200}
201
202#[inline(always)]
203fn read_rc_inner_with_type<T: 'static, C: Codec<T>>(
204 context: &mut ReadContext,
205 remote_field_type: &FieldType,
206) -> Result<T, Error> {
207 reserve_strong::<T>(context)?;
208 if codec_read_type_info::<T, C>(context, remote_field_type) {
212 return C::read(context, RefMode::None, true);
213 }
214 C::read_data_with_type(context, remote_field_type)
215}
216
217macro_rules! read_rc_weak_owner {
218 ($context:ident, $ref_mode:expr, $read_inner:expr) => {{
219 if $ref_mode != RefMode::Tracking {
220 return Err(weak_read_mode_error("RcWeak"));
221 }
222 match $context.ref_reader.read_ref_flag(&mut $context.reader)? {
223 RefFlag::Null => {
224 reserve_weak_cell::<std::rc::Weak<T>>($context)?;
225 Ok(RcWeak::new())
226 }
227 RefFlag::RefValue => {
228 $context.inc_depth()?;
229 let result = $read_inner;
230 $context.dec_depth();
231 let value = result?;
232 let strong = Rc::new(value);
233 let ref_id = $context.ref_reader.store_rc_ref(strong);
234 let strong = $context
235 .ref_reader
236 .get_rc_ref::<T>(ref_id)
237 .ok_or_else(|| weak_ref_missing_after_insert("Rc", ref_id))?;
238 reserve_weak_cell::<std::rc::Weak<T>>($context)?;
239 Ok(RcWeak::from(&strong))
240 }
241 RefFlag::Ref => {
242 let ref_id = $context.ref_reader.read_ref_id(&mut $context.reader)?;
243 reserve_weak_cell::<std::rc::Weak<T>>($context)?;
244 if let Some(strong) = $context.ref_reader.get_rc_ref::<T>(ref_id) {
245 return Ok(RcWeak::from(&strong));
246 }
247 let weak = RcWeak::new();
248 let callback_weak = weak.clone();
249 $context.ref_reader.add_callback(Box::new(move |reader| {
250 if let Some(strong) = reader.get_rc_ref::<T>(ref_id) {
251 callback_weak.update(Rc::downgrade(&strong));
252 }
253 }));
254 Ok(weak)
255 }
256 RefFlag::NotNullValue => Err(weak_untracked_value("RcWeak")),
257 }
258 }};
259}
260
261#[inline(always)]
262fn read_rc_weak<T: 'static, C: Serializer<Target = T>>(
263 context: &mut ReadContext,
264 ref_mode: RefMode,
265 read_type_info: bool,
266 type_info: Option<&Rc<TypeInfo>>,
267) -> Result<RcWeak<T>, Error> {
268 read_rc_weak_owner!(
269 context,
270 ref_mode,
271 read_rc_inner::<T, C>(context, read_type_info, type_info)
272 )
273}
274
275#[inline(always)]
276fn read_rc_weak_with_type<T: 'static, C: Codec<T>>(
277 context: &mut ReadContext,
278 ref_mode: RefMode,
279 remote_field_type: &FieldType,
280) -> Result<RcWeak<T>, Error> {
281 read_rc_weak_owner!(
282 context,
283 ref_mode,
284 read_rc_inner_with_type::<T, C>(context, remote_field_type)
285 )
286}
287
288impl<T, C, const NULLABLE: bool, const TRACK_REF: bool> Serializer
289 for RcWeakCodec<T, C, NULLABLE, TRACK_REF>
290where
291 T: 'static,
292 C: Serializer<Target = T>,
293{
294 type Target = RcWeak<T>;
295
296 #[inline(always)]
297 fn reserved_space() -> usize {
298 4
299 }
300
301 #[cold]
302 #[inline(never)]
303 fn write_data(_: &RcWeak<T>, _: &mut WriteContext) -> Result<(), Error> {
304 Err(Error::not_allowed(
305 "RcWeak must be written through its reference-tracking envelope",
306 ))
307 }
308
309 #[cold]
310 #[inline(never)]
311 fn read_data(_: &mut ReadContext) -> Result<RcWeak<T>, Error> {
312 Err(Error::not_allowed(
313 "RcWeak must be read through its reference-tracking envelope",
314 ))
315 }
316
317 #[inline(always)]
318 fn write(
319 value: &RcWeak<T>,
320 context: &mut WriteContext,
321 ref_mode: RefMode,
322 write_type_info: bool,
323 ) -> Result<(), Error> {
324 write_rc_weak::<T, C>(value, context, ref_mode, write_type_info)
325 }
326
327 #[inline(always)]
328 fn write_type_info_value(
329 context: &mut WriteContext,
330 target_type_id: std::any::TypeId,
331 ) -> Result<Rc<TypeInfo>, Error> {
332 C::write_type_info_value(context, target_type_id)
333 }
334
335 #[inline(always)]
336 fn write_with_type_info(
337 value: &RcWeak<T>,
338 context: &mut WriteContext,
339 ref_mode: RefMode,
340 type_info: &Rc<TypeInfo>,
341 ) -> Result<(), Error> {
342 write_rc_weak_with_type_info::<T, C>(value, context, ref_mode, type_info)
343 }
344
345 #[inline(always)]
346 fn read(
347 context: &mut ReadContext,
348 ref_mode: RefMode,
349 read_type_info: bool,
350 ) -> Result<RcWeak<T>, Error> {
351 read_rc_weak::<T, C>(context, ref_mode, read_type_info, None)
352 }
353
354 #[inline(always)]
355 fn read_with_type_info(
356 context: &mut ReadContext,
357 ref_mode: RefMode,
358 type_info: &Rc<TypeInfo>,
359 ) -> Result<RcWeak<T>, Error> {
360 read_rc_weak::<T, C>(context, ref_mode, false, Some(type_info))
361 }
362
363 #[inline(always)]
364 fn default_value(context: &mut ReadContext) -> Result<RcWeak<T>, Error> {
365 reserve_weak_cell::<std::rc::Weak<T>>(context)?;
366 Ok(RcWeak::new())
367 }
368
369 #[inline(always)]
370 fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
371 C::write_type_info(context)
372 }
373
374 #[inline(always)]
375 fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
376 C::read_type_info(context)
377 }
378
379 #[inline(always)]
380 fn static_type_id() -> TypeId {
381 C::static_type_id()
382 }
383
384 const IS_POLYMORPHIC: bool = C::IS_POLYMORPHIC;
385
386 const IS_SHARED_REF: bool = true;
387
388 const IS_WRAPPER: bool = true;
389
390 const REQUIRES_SCOPED_ACCESS: bool = true;
391
392 #[inline(always)]
393 fn dynamic_type_id(value: &RcWeak<T>) -> Result<Option<std::any::TypeId>, Error> {
394 match value.upgrade() {
395 Some(value) => C::dynamic_type_id(&value),
396 None => Ok(None),
397 }
398 }
399}
400
401impl<T, C, const NULLABLE: bool, const TRACK_REF: bool> Codec<RcWeak<T>>
402 for RcWeakCodec<T, C, NULLABLE, TRACK_REF>
403where
404 T: 'static,
405 C: Codec<T>,
406{
407 #[inline(always)]
408 fn field_type(type_resolver: &TypeResolver) -> Result<FieldType, Error> {
409 let mut field_type = C::field_type(type_resolver)?;
410 field_type.nullable = NULLABLE;
411 field_type.track_ref = true;
412 Ok(field_type)
413 }
414
415 #[inline(always)]
416 fn write_field(value: &RcWeak<T>, context: &mut WriteContext) -> Result<(), Error> {
417 Self::write_with_mode(
418 value,
419 context,
420 RefMode::Tracking,
421 super::codec::codec_write_type_info::<T, C>(context),
422 true,
423 )
424 }
425
426 #[inline(always)]
427 fn read_field(context: &mut ReadContext) -> Result<RcWeak<T>, Error> {
428 <Self as Serializer>::read(
429 context,
430 RefMode::Tracking,
431 codec_read_type_info_static::<T, C>(context),
432 )
433 }
434
435 #[inline(always)]
436 fn read_field_with_type(
437 context: &mut ReadContext,
438 remote_field_type: &FieldType,
439 ) -> Result<RcWeak<T>, Error> {
440 read_rc_weak_with_type::<T, C>(context, RefMode::Tracking, remote_field_type)
441 }
442
443 #[inline(always)]
444 fn write_with_mode(
445 value: &RcWeak<T>,
446 context: &mut WriteContext,
447 ref_mode: RefMode,
448 write_type_info: bool,
449 has_generics: bool,
450 ) -> Result<(), Error> {
451 write_rc_weak_field::<T, C>(value, context, ref_mode, write_type_info, has_generics)
452 }
453
454 #[inline(always)]
455 fn write_with_type_info(
456 value: &RcWeak<T>,
457 context: &mut WriteContext,
458 ref_mode: RefMode,
459 type_info: &Rc<TypeInfo>,
460 has_generics: bool,
461 ) -> Result<(), Error> {
462 write_rc_weak_field_with_type_info::<T, C>(
463 value,
464 context,
465 ref_mode,
466 type_info,
467 has_generics,
468 )
469 }
470
471 #[inline(always)]
472 fn read_type_info_value(
473 context: &mut ReadContext,
474 ) -> Result<super::codec::CodecReadType, Error> {
475 C::read_type_info_value(context)
476 }
477}
478
479#[inline(always)]
480fn arc_weak_body<T: Send + Sync + 'static>(
481 value: &ArcWeak<T>,
482 context: &mut WriteContext,
483 ref_mode: RefMode,
484) -> Result<Option<Arc<T>>, Error> {
485 if !context.is_track_ref() {
486 return Err(arc_weak_tracking_error());
487 }
488 if ref_mode != RefMode::Tracking {
489 return Err(weak_write_mode_error("ArcWeak"));
490 }
491 let Some(value) = value.upgrade() else {
492 context.writer.write_i8(RefFlag::Null as i8);
493 return Ok(None);
494 };
495 if context
496 .ref_writer
497 .try_write_arc_ref(&mut context.writer, &value)
498 {
499 return Ok(None);
500 }
501 Ok(Some(value))
502}
503
504#[inline(always)]
505fn write_arc_weak<T: Send + Sync + 'static, C: Serializer<Target = T>>(
506 value: &ArcWeak<T>,
507 context: &mut WriteContext,
508 ref_mode: RefMode,
509 write_type_info: bool,
510) -> Result<(), Error> {
511 let Some(value) = arc_weak_body(value, context, ref_mode)? else {
512 return Ok(());
513 };
514 C::write(&value, context, RefMode::None, write_type_info)
515}
516
517#[inline(always)]
518fn write_arc_weak_field<T: Send + Sync + 'static, C: Codec<T>>(
519 value: &ArcWeak<T>,
520 context: &mut WriteContext,
521 ref_mode: RefMode,
522 write_type_info: bool,
523 has_generics: bool,
524) -> Result<(), Error> {
525 let Some(value) = arc_weak_body(value, context, ref_mode)? else {
526 return Ok(());
527 };
528 C::write_with_mode(
529 &value,
530 context,
531 RefMode::None,
532 write_type_info,
533 has_generics,
534 )
535}
536
537#[inline(always)]
538fn write_arc_weak_with_type_info<T: Send + Sync + 'static, C: Serializer<Target = T>>(
539 value: &ArcWeak<T>,
540 context: &mut WriteContext,
541 ref_mode: RefMode,
542 type_info: &Rc<TypeInfo>,
543) -> Result<(), Error> {
544 let Some(value) = arc_weak_body(value, context, ref_mode)? else {
545 return Ok(());
546 };
547 C::write_with_type_info(&value, context, RefMode::None, type_info)
548}
549
550#[inline(always)]
551fn write_arc_weak_field_with_type_info<T: Send + Sync + 'static, C: Codec<T>>(
552 value: &ArcWeak<T>,
553 context: &mut WriteContext,
554 ref_mode: RefMode,
555 type_info: &Rc<TypeInfo>,
556 has_generics: bool,
557) -> Result<(), Error> {
558 let Some(value) = arc_weak_body(value, context, ref_mode)? else {
559 return Ok(());
560 };
561 <C as Codec<T>>::write_with_type_info(&value, context, RefMode::None, type_info, has_generics)
562}
563
564#[inline(always)]
565fn read_arc_inner<T: Send + Sync + 'static, C: Serializer<Target = T>>(
566 context: &mut ReadContext,
567 read_type_info: bool,
568 type_info: Option<&Rc<TypeInfo>>,
569) -> Result<T, Error> {
570 reserve_strong::<T>(context)?;
571 if let Some(type_info) = type_info {
572 return C::read_with_type_info(context, RefMode::None, type_info);
573 }
574 C::read(context, RefMode::None, read_type_info)
577}
578
579#[inline(always)]
580fn read_arc_inner_with_type<T: Send + Sync + 'static, C: Codec<T>>(
581 context: &mut ReadContext,
582 remote_field_type: &FieldType,
583) -> Result<T, Error> {
584 reserve_strong::<T>(context)?;
585 if codec_read_type_info::<T, C>(context, remote_field_type) {
589 return C::read(context, RefMode::None, true);
590 }
591 C::read_data_with_type(context, remote_field_type)
592}
593
594macro_rules! read_arc_weak_owner {
595 ($context:ident, $ref_mode:expr, $read_inner:expr) => {{
596 if $ref_mode != RefMode::Tracking {
597 return Err(weak_read_mode_error("ArcWeak"));
598 }
599 match $context.ref_reader.read_ref_flag(&mut $context.reader)? {
600 RefFlag::Null => {
601 reserve_weak_cell::<std::sync::Weak<T>>($context)?;
602 Ok(ArcWeak::new())
603 }
604 RefFlag::RefValue => {
605 $context.inc_depth()?;
606 let result = $read_inner;
607 $context.dec_depth();
608 let value = result?;
609 let strong = Arc::new(value);
610 let ref_id = $context.ref_reader.store_arc_ref(strong);
611 let strong = $context
612 .ref_reader
613 .get_arc_ref::<T>(ref_id)
614 .ok_or_else(|| weak_ref_missing_after_insert("Arc", ref_id))?;
615 reserve_weak_cell::<std::sync::Weak<T>>($context)?;
616 Ok(ArcWeak::from(&strong))
617 }
618 RefFlag::Ref => {
619 let ref_id = $context.ref_reader.read_ref_id(&mut $context.reader)?;
620 reserve_weak_cell::<std::sync::Weak<T>>($context)?;
621 let weak = ArcWeak::new();
622 if let Some(strong) = $context.ref_reader.get_arc_ref::<T>(ref_id) {
623 weak.update(Arc::downgrade(&strong));
624 } else {
625 let callback_weak = weak.clone();
626 $context.ref_reader.add_callback(Box::new(move |reader| {
627 if let Some(strong) = reader.get_arc_ref::<T>(ref_id) {
628 callback_weak.update(Arc::downgrade(&strong));
629 }
630 }));
631 }
632 Ok(weak)
633 }
634 RefFlag::NotNullValue => Err(weak_untracked_value("ArcWeak")),
635 }
636 }};
637}
638
639#[inline(always)]
640fn read_arc_weak<T: Send + Sync + 'static, C: Serializer<Target = T>>(
641 context: &mut ReadContext,
642 ref_mode: RefMode,
643 read_type_info: bool,
644 type_info: Option<&Rc<TypeInfo>>,
645) -> Result<ArcWeak<T>, Error> {
646 read_arc_weak_owner!(
647 context,
648 ref_mode,
649 read_arc_inner::<T, C>(context, read_type_info, type_info)
650 )
651}
652
653#[inline(always)]
654fn read_arc_weak_with_type<T: Send + Sync + 'static, C: Codec<T>>(
655 context: &mut ReadContext,
656 ref_mode: RefMode,
657 remote_field_type: &FieldType,
658) -> Result<ArcWeak<T>, Error> {
659 read_arc_weak_owner!(
660 context,
661 ref_mode,
662 read_arc_inner_with_type::<T, C>(context, remote_field_type)
663 )
664}
665
666impl<T, C, const NULLABLE: bool, const TRACK_REF: bool> Serializer
667 for ArcWeakCodec<T, C, NULLABLE, TRACK_REF>
668where
669 T: Send + Sync + 'static,
670 C: Serializer<Target = T>,
671{
672 type Target = ArcWeak<T>;
673
674 #[inline(always)]
675 fn reserved_space() -> usize {
676 4
677 }
678
679 #[cold]
680 #[inline(never)]
681 fn write_data(_: &ArcWeak<T>, _: &mut WriteContext) -> Result<(), Error> {
682 Err(Error::not_allowed(
683 "ArcWeak must be written through its reference-tracking envelope",
684 ))
685 }
686
687 #[cold]
688 #[inline(never)]
689 fn read_data(_: &mut ReadContext) -> Result<ArcWeak<T>, Error> {
690 Err(Error::not_allowed(
691 "ArcWeak must be read through its reference-tracking envelope",
692 ))
693 }
694
695 #[inline(always)]
696 fn write(
697 value: &ArcWeak<T>,
698 context: &mut WriteContext,
699 ref_mode: RefMode,
700 write_type_info: bool,
701 ) -> Result<(), Error> {
702 write_arc_weak::<T, C>(value, context, ref_mode, write_type_info)
703 }
704
705 #[inline(always)]
706 fn write_type_info_value(
707 context: &mut WriteContext,
708 target_type_id: std::any::TypeId,
709 ) -> Result<Rc<TypeInfo>, Error> {
710 C::write_type_info_value(context, target_type_id)
711 }
712
713 #[inline(always)]
714 fn write_with_type_info(
715 value: &ArcWeak<T>,
716 context: &mut WriteContext,
717 ref_mode: RefMode,
718 type_info: &Rc<TypeInfo>,
719 ) -> Result<(), Error> {
720 write_arc_weak_with_type_info::<T, C>(value, context, ref_mode, type_info)
721 }
722
723 #[inline(always)]
724 fn read(
725 context: &mut ReadContext,
726 ref_mode: RefMode,
727 read_type_info: bool,
728 ) -> Result<ArcWeak<T>, Error> {
729 read_arc_weak::<T, C>(context, ref_mode, read_type_info, None)
730 }
731
732 #[inline(always)]
733 fn read_with_type_info(
734 context: &mut ReadContext,
735 ref_mode: RefMode,
736 type_info: &Rc<TypeInfo>,
737 ) -> Result<ArcWeak<T>, Error> {
738 read_arc_weak::<T, C>(context, ref_mode, false, Some(type_info))
739 }
740
741 #[inline(always)]
742 fn default_value(context: &mut ReadContext) -> Result<ArcWeak<T>, Error> {
743 reserve_weak_cell::<std::sync::Weak<T>>(context)?;
744 Ok(ArcWeak::new())
745 }
746
747 #[inline(always)]
748 fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
749 C::write_type_info(context)
750 }
751
752 #[inline(always)]
753 fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
754 C::read_type_info(context)
755 }
756
757 #[inline(always)]
758 fn static_type_id() -> TypeId {
759 C::static_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);