1use crate::error::Error;
125use crate::resolver::context::{ReadContext, WriteContext};
126use crate::resolver::type_resolver::{TypeInfo, TypeResolver};
127use crate::serializer::{ForyDefault, Serializer};
128use crate::types::{RefFlag, RefMode, TypeId};
129use std::cell::UnsafeCell;
130use std::rc::Rc;
131use std::sync::Arc;
132
133pub struct RcWeak<T: ?Sized> {
149 inner: Rc<UnsafeCell<std::rc::Weak<T>>>,
151}
152
153impl<T: ?Sized> std::fmt::Debug for RcWeak<T> {
154 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155 f.debug_struct("RcWeak")
156 .field("strong_count", &self.strong_count())
157 .field("weak_count", &self.weak_count())
158 .finish()
159 }
160}
161
162impl<T> RcWeak<T> {
163 pub fn new() -> Self {
164 RcWeak {
165 inner: Rc::new(UnsafeCell::new(std::rc::Weak::new())),
166 }
167 }
168}
169
170impl<T: ?Sized> RcWeak<T> {
171 pub fn upgrade(&self) -> Option<Rc<T>> {
172 unsafe { (*self.inner.get()).upgrade() }
173 }
174
175 pub fn strong_count(&self) -> usize {
176 unsafe { (*self.inner.get()).strong_count() }
177 }
178
179 pub fn weak_count(&self) -> usize {
180 unsafe { (*self.inner.get()).weak_count() }
181 }
182
183 pub fn ptr_eq(&self, other: &Self) -> bool {
184 unsafe { std::rc::Weak::ptr_eq(&*self.inner.get(), &*other.inner.get()) }
185 }
186
187 pub fn update(&self, weak: std::rc::Weak<T>) {
188 unsafe {
189 *self.inner.get() = weak;
190 }
191 }
192
193 pub fn from_std(weak: std::rc::Weak<T>) -> Self {
194 RcWeak {
195 inner: Rc::new(UnsafeCell::new(weak)),
196 }
197 }
198}
199
200impl<T: ?Sized> PartialEq for RcWeak<T> {
201 fn eq(&self, other: &Self) -> bool {
202 self.ptr_eq(other)
203 }
204}
205
206impl<T: ?Sized> Eq for RcWeak<T> {}
207
208impl<T> Default for RcWeak<T> {
209 fn default() -> Self {
210 Self::new()
211 }
212}
213
214impl<T: ?Sized> Clone for RcWeak<T> {
215 fn clone(&self) -> Self {
216 RcWeak {
218 inner: self.inner.clone(),
219 }
220 }
221}
222
223impl<T: ?Sized> From<&Rc<T>> for RcWeak<T> {
224 fn from(rc: &Rc<T>) -> Self {
225 RcWeak::from_std(Rc::downgrade(rc))
226 }
227}
228
229unsafe impl<T: ?Sized> Send for RcWeak<T> where std::rc::Weak<T>: Send {}
230unsafe impl<T: ?Sized> Sync for RcWeak<T> where std::rc::Weak<T>: Sync {}
231
232pub struct ArcWeak<T: ?Sized> {
243 inner: Arc<UnsafeCell<std::sync::Weak<T>>>,
245}
246
247impl<T: ?Sized> std::fmt::Debug for ArcWeak<T> {
248 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
249 f.debug_struct("ArcWeak")
250 .field("strong_count", &self.strong_count())
251 .field("weak_count", &self.weak_count())
252 .finish()
253 }
254}
255
256impl<T> ArcWeak<T> {
257 pub fn new() -> Self {
258 ArcWeak {
259 inner: Arc::new(UnsafeCell::new(std::sync::Weak::new())),
260 }
261 }
262}
263
264impl<T: ?Sized> ArcWeak<T> {
265 pub fn upgrade(&self) -> Option<Arc<T>> {
266 unsafe { (*self.inner.get()).upgrade() }
267 }
268
269 pub fn strong_count(&self) -> usize {
270 unsafe { (*self.inner.get()).strong_count() }
271 }
272
273 pub fn weak_count(&self) -> usize {
274 unsafe { (*self.inner.get()).weak_count() }
275 }
276
277 pub fn ptr_eq(&self, other: &Self) -> bool {
278 unsafe { std::sync::Weak::ptr_eq(&*self.inner.get(), &*other.inner.get()) }
279 }
280
281 pub fn update(&self, weak: std::sync::Weak<T>) {
282 unsafe {
283 *self.inner.get() = weak;
284 }
285 }
286
287 pub fn from_std(weak: std::sync::Weak<T>) -> Self {
288 ArcWeak {
289 inner: Arc::new(UnsafeCell::new(weak)),
290 }
291 }
292}
293
294impl<T: ?Sized> PartialEq for ArcWeak<T> {
295 fn eq(&self, other: &Self) -> bool {
296 self.ptr_eq(other)
297 }
298}
299
300impl<T: ?Sized> Eq for ArcWeak<T> {}
301
302impl<T> Default for ArcWeak<T> {
303 fn default() -> Self {
304 Self::new()
305 }
306}
307
308impl<T: ?Sized> Clone for ArcWeak<T> {
309 fn clone(&self) -> Self {
310 ArcWeak {
312 inner: self.inner.clone(),
313 }
314 }
315}
316
317impl<T: ?Sized> From<&Arc<T>> for ArcWeak<T> {
318 fn from(arc: &Arc<T>) -> Self {
319 ArcWeak::from_std(Arc::downgrade(arc))
320 }
321}
322
323unsafe impl<T: ?Sized + Send + Sync> Send for ArcWeak<T> {}
324unsafe impl<T: ?Sized + Send + Sync> Sync for ArcWeak<T> {}
325
326impl<T: Serializer + ForyDefault + 'static> Serializer for RcWeak<T> {
327 fn fory_is_shared_ref() -> bool {
328 true
329 }
330
331 fn fory_write(
332 &self,
333 context: &mut WriteContext,
334 ref_mode: RefMode,
335 write_type_info: bool,
336 has_generics: bool,
337 ) -> Result<(), Error> {
338 if !context.is_track_ref() {
340 return Err(Error::invalid_ref(
341 "RcWeak requires track_ref to be enabled. Use Fory::default().track_ref(true)",
342 ));
343 }
344 if ref_mode != RefMode::Tracking {
346 return Err(Error::invalid_ref(
347 "RcWeak requires RefMode::Tracking for serialization",
348 ));
349 }
350 if let Some(rc) = self.upgrade() {
351 if !context
352 .ref_writer
353 .try_write_rc_ref(&mut context.writer, &rc)
354 {
355 if write_type_info {
356 T::fory_write_type_info(context)?;
357 }
358 T::fory_write_data_generic(&*rc, context, has_generics)?;
359 }
360 } else {
361 context.writer.write_i8(RefFlag::Null as i8);
362 }
363 Ok(())
364 }
365
366 fn fory_write_data_generic(&self, _: &mut WriteContext, _: bool) -> Result<(), Error> {
367 Err(Error::not_allowed(
368 "RcWeak<T> should be written using `fory_write` to handle reference tracking properly",
369 ))
370 }
371
372 fn fory_write_data(&self, _: &mut WriteContext) -> Result<(), Error> {
373 Err(Error::not_allowed(
374 "RcWeak<T> should be written using `fory_write` to handle reference tracking properly",
375 ))
376 }
377
378 fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
379 T::fory_write_type_info(context)
380 }
381
382 fn fory_read(
383 context: &mut ReadContext,
384 ref_mode: RefMode,
385 read_type_info: bool,
386 ) -> Result<Self, Error> {
387 debug_assert!(
389 ref_mode == RefMode::Tracking,
390 "RcWeak requires RefMode::Tracking"
391 );
392 read_rc_weak::<T>(context, read_type_info, None)
393 }
394
395 fn fory_read_with_type_info(
396 context: &mut ReadContext,
397 ref_mode: RefMode,
398 typeinfo: Rc<TypeInfo>,
399 ) -> Result<Self, Error> {
400 debug_assert!(
401 ref_mode == RefMode::Tracking,
402 "RcWeak requires RefMode::Tracking"
403 );
404 read_rc_weak::<T>(context, false, Some(typeinfo))
405 }
406
407 fn fory_read_data(_: &mut ReadContext) -> Result<Self, Error> {
408 Err(Error::not_allowed("RcWeak<T> should be written using `fory_read/fory_read_with_type_info` to handle reference tracking properly"))
409 }
410
411 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
412 T::fory_read_type_info(context)
413 }
414
415 fn fory_reserved_space() -> usize {
416 4
418 }
419
420 fn fory_get_type_id(type_resolver: &TypeResolver) -> Result<TypeId, Error> {
421 T::fory_get_type_id(type_resolver)
422 }
423
424 fn fory_get_type_info(type_resolver: &TypeResolver) -> Result<Rc<TypeInfo>, Error> {
425 match type_resolver.get_type_info(&std::any::TypeId::of::<T>()) {
426 Ok(info) => Ok(info),
427 Err(e) => Err(Error::enhance_type_error::<T>(e)),
428 }
429 }
430
431 fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<TypeId, Error> {
432 if let Some(rc) = self.upgrade() {
433 (*rc).fory_type_id_dyn(type_resolver)
434 } else {
435 T::fory_get_type_id(type_resolver)
436 }
437 }
438
439 fn fory_static_type_id() -> TypeId {
440 T::fory_static_type_id()
441 }
442
443 fn as_any(&self) -> &dyn std::any::Any {
444 self
445 }
446}
447
448fn read_rc_weak<T: Serializer + ForyDefault + 'static>(
449 context: &mut ReadContext,
450 read_type_info: bool,
451 type_info: Option<Rc<TypeInfo>>,
452) -> Result<RcWeak<T>, Error> {
453 let ref_flag = context.ref_reader.read_ref_flag(&mut context.reader)?;
455 match ref_flag {
456 RefFlag::Null => Ok(RcWeak::new()),
457 RefFlag::RefValue => {
458 context.inc_depth()?;
459 let data = if let Some(type_info) = type_info {
460 T::fory_read_with_type_info(context, RefMode::None, type_info)?
461 } else {
462 if read_type_info {
463 context.read_any_type_info()?;
464 }
465 T::fory_read_data(context)?
466 };
467 context.dec_depth();
468 let rc = Rc::new(data);
469 let ref_id = context.ref_reader.store_rc_ref(rc);
470 let rc = context.ref_reader.get_rc_ref::<T>(ref_id).unwrap();
471 Ok(RcWeak::from(&rc))
472 }
473 RefFlag::Ref => {
474 let ref_id = context.ref_reader.read_ref_id(&mut context.reader)?;
475 if let Some(rc) = context.ref_reader.get_rc_ref::<T>(ref_id) {
476 Ok(RcWeak::from(&rc))
477 } else {
478 let result_weak = RcWeak::new();
479 let callback_weak = result_weak.clone();
480 context.ref_reader.add_callback(Box::new(move |ref_reader| {
481 if let Some(rc) = ref_reader.get_rc_ref::<T>(ref_id) {
482 callback_weak.update(Rc::downgrade(&rc));
483 }
484 }));
485
486 Ok(result_weak)
487 }
488 }
489 RefFlag::NotNullValue => Err(Error::invalid_ref("RcWeak can't hold a strong ref value")),
490 }
491}
492
493impl<T: ForyDefault> ForyDefault for RcWeak<T> {
494 fn fory_default() -> Self {
495 RcWeak::new()
496 }
497}
498
499impl<T: Serializer + ForyDefault + Send + Sync + 'static> Serializer for ArcWeak<T> {
500 fn fory_is_shared_ref() -> bool {
501 true
502 }
503
504 fn fory_write(
505 &self,
506 context: &mut WriteContext,
507 ref_mode: RefMode,
508 write_type_info: bool,
509 has_generics: bool,
510 ) -> Result<(), Error> {
511 if !context.is_track_ref() {
513 return Err(Error::invalid_ref(
514 "ArcWeak requires track_ref to be enabled. Use Fory::default().track_ref(true)",
515 ));
516 }
517 if ref_mode != RefMode::Tracking {
519 return Err(Error::invalid_ref(
520 "ArcWeak requires RefMode::Tracking for serialization",
521 ));
522 }
523 if let Some(arc) = self.upgrade() {
524 if !context
525 .ref_writer
526 .try_write_arc_ref(&mut context.writer, &arc)
527 {
528 if write_type_info {
529 T::fory_write_type_info(context)?;
530 }
531 T::fory_write_data_generic(&*arc, context, has_generics)?;
532 }
533 } else {
534 context.writer.write_i8(RefFlag::Null as i8);
535 }
536 Ok(())
537 }
538
539 fn fory_write_data_generic(&self, _: &mut WriteContext, _: bool) -> Result<(), Error> {
540 Err(Error::not_allowed(
541 "ArcWeak<T> should be written using `fory_write` to handle reference tracking properly",
542 ))
543 }
544
545 fn fory_write_data(&self, _: &mut WriteContext) -> Result<(), Error> {
546 Err(Error::not_allowed(
547 "ArcWeak<T> should be written using `fory_write` to handle reference tracking properly",
548 ))
549 }
550
551 fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
552 T::fory_write_type_info(context)
553 }
554
555 fn fory_read(
556 context: &mut ReadContext,
557 ref_mode: RefMode,
558 read_type_info: bool,
559 ) -> Result<Self, Error> {
560 debug_assert!(
562 ref_mode == RefMode::Tracking,
563 "ArcWeak requires RefMode::Tracking"
564 );
565 read_arc_weak(context, read_type_info, None)
566 }
567
568 fn fory_read_with_type_info(
569 context: &mut ReadContext,
570 ref_mode: RefMode,
571 typeinfo: Rc<TypeInfo>,
572 ) -> Result<Self, Error> {
573 debug_assert!(
574 ref_mode == RefMode::Tracking,
575 "ArcWeak requires RefMode::Tracking"
576 );
577 read_arc_weak::<T>(context, false, Some(typeinfo))
578 }
579
580 fn fory_read_data(_: &mut ReadContext) -> Result<Self, Error> {
581 Err(Error::not_allowed("ArcWeak<T> should be written using `fory_read/fory_read_with_type_info` to handle reference tracking properly"))
582 }
583
584 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
585 T::fory_read_type_info(context)
586 }
587
588 fn fory_reserved_space() -> usize {
589 4
591 }
592
593 fn fory_get_type_id(type_resolver: &TypeResolver) -> Result<TypeId, Error> {
594 T::fory_get_type_id(type_resolver)
595 }
596
597 fn fory_get_type_info(type_resolver: &TypeResolver) -> Result<Rc<TypeInfo>, Error> {
598 match type_resolver.get_type_info(&std::any::TypeId::of::<T>()) {
599 Ok(info) => Ok(info),
600 Err(e) => Err(Error::enhance_type_error::<T>(e)),
601 }
602 }
603
604 fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<TypeId, Error> {
605 if let Some(arc) = self.upgrade() {
606 (*arc).fory_type_id_dyn(type_resolver)
607 } else {
608 T::fory_get_type_id(type_resolver)
609 }
610 }
611
612 fn fory_static_type_id() -> TypeId {
613 T::fory_static_type_id()
614 }
615
616 fn as_any(&self) -> &dyn std::any::Any {
617 self
618 }
619}
620
621fn read_arc_weak<T: Serializer + ForyDefault + 'static>(
622 context: &mut ReadContext,
623 read_type_info: bool,
624 type_info: Option<Rc<TypeInfo>>,
625) -> Result<ArcWeak<T>, Error> {
626 let ref_flag = context.ref_reader.read_ref_flag(&mut context.reader)?;
628 match ref_flag {
629 RefFlag::Null => Ok(ArcWeak::new()),
630 RefFlag::RefValue => {
631 context.inc_depth()?;
632 let data = if let Some(type_info) = type_info {
633 T::fory_read_with_type_info(context, RefMode::None, type_info)?
634 } else {
635 if read_type_info {
636 context.read_any_type_info()?;
637 }
638 T::fory_read_data(context)?
639 };
640 context.dec_depth();
641 let arc = Arc::new(data);
642 let ref_id = context.ref_reader.store_arc_ref(arc);
643 let arc = context.ref_reader.get_arc_ref::<T>(ref_id).unwrap();
644 let weak = ArcWeak::from(&arc);
645 Ok(weak)
646 }
647 RefFlag::Ref => {
648 let ref_id = context.ref_reader.read_ref_id(&mut context.reader)?;
649 let weak = ArcWeak::new();
650
651 if let Some(arc) = context.ref_reader.get_arc_ref::<T>(ref_id) {
652 weak.update(Arc::downgrade(&arc));
653 } else {
654 let weak_ptr = weak.inner.get();
656 context.ref_reader.add_callback(Box::new(move |ref_reader| {
657 if let Some(arc) = ref_reader.get_arc_ref::<T>(ref_id) {
658 unsafe {
659 *weak_ptr = Arc::downgrade(&arc);
660 }
661 }
662 }));
663 }
664 Ok(weak)
665 }
666 RefFlag::NotNullValue => Err(Error::invalid_ref("ArcWeak can't hold a strong ref value")),
667 }
668}
669
670impl<T: ForyDefault> ForyDefault for ArcWeak<T> {
671 fn fory_default() -> Self {
672 ArcWeak::new()
673 }
674}