Skip to main content

serde_saphyr/
anchors.rs

1//! Support for YAML anchors and aliases using smart pointers.
2//!
3//! This module provides wrappers around [`Rc`] and [`Arc`] (and their weak counterparts)
4//! to enable the serialization and deserialization of shared or recursive structures
5//! in YAML.
6//!
7//! ## Anchor Types
8//!
9//! There are two main categories of anchor types provided:
10//!
11//! 1. **Standard Anchors** ([`RcAnchor`], [`ArcAnchor`], [`RcWeakAnchor`], [`ArcWeakAnchor`]):
12//!    - Designed for **Directed Acyclic Graphs (DAGs)** where multiple fields share ownership
13//!      of the same object.
14//!    - During deserialization, the strong anchor must be fully parsed before any of its aliases
15//!      (weak anchors) are encountered.
16//!    - These types are simpler to use because they implement [`Deref`] directly to the inner type `T`.
17//!
18//! 2. **Recursive Anchors** ([`RcRecursive`], [`ArcRecursive`], [`RcRecursion`], [`ArcRecursion`]):
19//!    - Specifically designed for **circular or recursive graphs** (e.g., an object that
20//!      contains a reference to itself).
21//!    - They allow an object to be referenced via an alias *before* it has been fully deserialized.
22//!
23//! ## Recursive Anchors Are More Complex
24//!
25//! Recursive anchors require a more complex internal structure because they must handle late
26//! initialization. When the deserializer encounters a recursive anchor, it creates a placeholder
27//! and registers it. Once the object's data is fully parsed, the placeholder is updated with the
28//! actual value. This requires interior mutability to fill in the value after the container has
29//! already been shared, and optionality ([`Option`]) to represent the uninitialized state.
30//!
31//! Because of this, you cannot [`Deref`] directly to `T`. Instead, you must use methods like
32//! [`.borrow()`](RcRecursive::borrow) or [`.lock()`](ArcRecursive::lock) to access the underlying data.
33//!
34//! For a complete working example of recursive anchors, see `examples/recursive_yaml.rs`.
35//!
36//! ## Limitation: `#[serde(flatten)]` buffering and strong-anchor identity
37//!
38//! Serde may buffer flattened content through internal content deserializers that do not
39//! preserve format-local anchor metadata. In those paths, `RcAnchor` / `ArcAnchor` value
40//! deserialization still succeeds, but full strong-pointer identity may be lost for nested
41//! anchors inside flattened payloads.
42
43use std::borrow::Borrow;
44use std::cell::RefCell;
45use std::fmt;
46#[cfg(feature = "deserialize")]
47use std::marker::PhantomData;
48use std::ops::Deref;
49use std::rc::{Rc, Weak as RcWeak};
50use std::sync::{Arc, Mutex, Weak as ArcWeak};
51
52#[cfg(feature = "deserialize")]
53use serde_core::de::{Error as _, Visitor};
54
55#[cfg(feature = "deserialize")]
56use crate::anchor_store;
57
58/// A wrapper around [`Rc<T>`] that opts a field into **anchor emission** (e.g. serialization by reference).
59///
60/// This type behaves like a normal [`Rc<T>`] but signals that the value
61/// should be treated as an *anchorable* reference — for instance,
62/// when serializing graphs or shared structures where pointer identity matters.
63///
64/// # Examples
65///
66/// ```
67/// use std::rc::Rc;
68/// use serde_saphyr::RcAnchor;
69///
70/// // Create from an existing Rc
71/// let rc = Rc::new(String::from("Hello"));
72/// let anchor1 = RcAnchor::from(rc.clone());
73///
74/// // Or directly from a value (Rc::new is called internally)
75/// let anchor2: RcAnchor<String> = RcAnchor::from(Rc::new(String::from("World")));
76///
77/// assert_eq!(*anchor1.0, "Hello");
78/// assert_eq!(*anchor2.0, "World");
79/// ```
80#[repr(transparent)]
81#[derive(Clone)]
82pub struct RcAnchor<T>(pub Rc<T>);
83
84/// A wrapper around [`Arc<T>`] that opts a field into **anchor emission** (e.g. serialization by reference).
85///
86/// It behaves exactly like an [`Arc<T>`] but explicitly marks shared ownership
87/// as an *anchor* for reference tracking or cross-object linking.
88///
89/// # Examples
90///
91/// ```
92/// use std::sync::Arc;
93/// use serde_saphyr::ArcAnchor;
94///
95/// // Create from an existing Arc
96/// let arc = Arc::new(String::from("Shared"));
97/// let anchor1 = ArcAnchor::from(arc.clone());
98///
99/// // Or create directly from a value
100/// let anchor2: ArcAnchor<String> = ArcAnchor::from(Arc::new(String::from("Data")));
101///
102/// assert_eq!(*anchor1.0, "Shared");
103/// assert_eq!(*anchor2.0, "Data");
104/// ```
105#[repr(transparent)]
106#[derive(Clone)]
107pub struct ArcAnchor<T>(pub Arc<T>);
108
109/// A wrapper around [`std::rc::Weak<T>`] that opts into **anchor emission**.
110///
111/// When serialized, if the weak reference is **dangling** (i.e., the value was dropped),
112/// it emits `null` to indicate that the target no longer exists.
113/// Provides convenience methods like [`upgrade`](Self::upgrade) and [`is_dangling`](Self::is_dangling).
114///
115/// > **Note on deserialization:** `null` deserializes back into a dangling weak (`Weak::new()`).
116/// > Non-`null` is resolved through the YAML anchor context; it is rejected when no matching
117/// > strong anchor is available.
118///
119/// # Examples
120///
121/// ```
122/// use std::rc::Rc;
123/// use serde_saphyr::{RcAnchor, RcWeakAnchor};
124///
125/// let rc_anchor = RcAnchor::from(Rc::new(String::from("Persistent")));
126///
127/// // Create a weak anchor from a strong reference
128/// let weak_anchor = RcWeakAnchor::from(&rc_anchor.0);
129///
130/// assert!(weak_anchor.upgrade().is_some());
131/// drop(rc_anchor);
132/// assert!(weak_anchor.upgrade().is_none());
133/// ```
134#[repr(transparent)]
135#[derive(Clone)]
136pub struct RcWeakAnchor<T>(pub RcWeak<T>);
137
138/// A wrapper around [`std::sync::Weak<T>`] that opts into **anchor emission**.
139///
140/// This variant is thread-safe and uses [`Arc`] / [`Weak`](std::sync::Weak) instead of [`Rc`].
141/// If the weak reference is **dangling**, it serializes as `null`.
142///
143/// > **Deserialization note:** `null` → dangling weak. Non-`null` is rejected unless a registry is used.
144///
145/// # Examples
146///
147/// ```
148/// use std::sync::Arc;
149/// use serde_saphyr::{ArcAnchor, ArcWeakAnchor};
150///
151/// let arc_anchor = ArcAnchor::from(Arc::new(String::from("Thread-safe")));
152///
153/// // Create a weak anchor from the strong reference
154/// let weak_anchor = ArcWeakAnchor::from(&arc_anchor.0);
155///
156/// assert!(weak_anchor.upgrade().is_some());
157/// drop(arc_anchor);
158/// assert!(weak_anchor.upgrade().is_none());
159/// ```
160#[repr(transparent)]
161#[derive(Clone)]
162pub struct ArcWeakAnchor<T>(pub ArcWeak<T>);
163
164/// The parent (origin) anchor definition that may have recursive references to it.
165/// This type provides the value for the references and must be placed where the original value is defined.
166/// Fields that reference this value (possibly recursively) must be wrapped in [`RcRecursion`].
167/// ```rust
168/// # #[cfg(feature = "deserialize")]
169/// # {
170/// use std::cell::Ref;
171/// use serde::Deserialize;
172/// use serde_saphyr::{RcRecursion, RcRecursive};
173/// #[derive(Deserialize)]
174/// struct King {
175///     name: String,
176///     coronator: RcRecursion<King>, // who crowned this king
177/// }
178///
179/// #[derive(Deserialize)]
180/// struct Kingdom {
181///     king: RcRecursive<King>,
182/// }
183///     let yaml = r#"
184/// king: &root
185///   name: "Aurelian I"
186///   coronator: *root # this king crowned himself
187/// "#;
188///
189/// let kingdom_data: Kingdom = serde_saphyr::from_str(yaml).unwrap();
190///     let king: Ref<King> = kingdom_data.king.borrow();
191///     let coronator = king
192///         .coronator
193///         .upgrade().expect("coronator always exists");
194///     let coronator_name = &coronator.borrow().name;
195///     assert_eq!(coronator_name, "Aurelian I");
196/// # }
197/// ```
198#[repr(transparent)]
199#[derive(Clone)]
200pub struct RcRecursive<T>(pub Rc<RefCell<Option<T>>>);
201
202/// The parent (origin) anchor definition that may have recursive references to it.
203/// This type provides the value for the references and must be placed where the original value is defined.
204/// Fields that reference this value (possibly recursively) must be wrapped in [`ArcRecursion`].
205/// ```rust
206/// # #[cfg(feature = "deserialize")]
207/// # {
208/// use serde::Deserialize;
209/// use serde_saphyr::{ArcRecursion, ArcRecursive};
210///
211/// #[derive(Deserialize)]
212/// struct King {
213///     name: String,
214///     coronator: ArcRecursion<King>, // who crowned this king
215/// }
216///
217/// #[derive(Deserialize)]
218/// struct Kingdom {
219///     king: ArcRecursive<King>,
220/// }
221///
222///     let yaml = r#"
223/// king: &root
224///   name: "Aurelian I"
225///   coronator: *root # this king crowned himself
226/// "#;
227///
228///     let kingdom_data: Kingdom = serde_saphyr::from_str(yaml).unwrap();
229///     let coronator = {
230///         let king_guard = kingdom_data.king.lock().unwrap();
231///         let king = king_guard.as_ref().expect("king should be initialized");
232///         king.coronator
233///             .upgrade()
234///             .expect("coronator should be alive")
235///     };
236///
237///     let coronator_guard = coronator.lock().unwrap();
238///     let coronator_ref = coronator_guard
239///         .as_ref()
240///         .expect("coronator should be initialized");
241///     assert_eq!(coronator_ref.name, "Aurelian I");
242/// # }
243/// ```
244#[repr(transparent)]
245#[derive(Clone)]
246pub struct ArcRecursive<T>(pub Arc<Mutex<Option<T>>>);
247
248/// The possibly recursive reference to the parent anchor that must be [`RcRecursive`].
249/// See [`RcRecursive`] for code example.
250#[repr(transparent)]
251#[derive(Clone)]
252pub struct RcRecursion<T>(pub RcWeak<RefCell<Option<T>>>);
253
254/// Thread-safe recursive reference to a parent [`ArcRecursive`] anchor.
255/// It is more complex to use than [`RcRecursive`] because you must lock it before accessing the value.
256/// See [`ArcRecursive`] for code example.
257#[repr(transparent)]
258#[derive(Clone)]
259pub struct ArcRecursion<T>(pub ArcWeak<Mutex<Option<T>>>);
260
261// ===== From conversions (strong -> anchor) =====
262
263impl<T> From<Rc<T>> for RcAnchor<T> {
264    fn from(rc: Rc<T>) -> Self {
265        RcAnchor(rc)
266    }
267}
268
269impl<T> RcAnchor<T> {
270    /// Wrap a value in a new anchored [`Rc`].
271    #[must_use]
272    pub fn wrapping(x: T) -> Self {
273        RcAnchor(Rc::new(x))
274    }
275}
276
277impl<T> ArcAnchor<T> {
278    /// Wrap a value in a new anchored [`Arc`].
279    #[must_use]
280    pub fn wrapping(x: T) -> Self {
281        ArcAnchor(Arc::new(x))
282    }
283}
284
285impl<T> From<Arc<T>> for ArcAnchor<T> {
286    #[inline]
287    fn from(arc: Arc<T>) -> Self {
288        ArcAnchor(arc)
289    }
290}
291
292// ===== From conversions (strong -> weak anchor) =====
293
294impl<T> From<&Rc<T>> for RcWeakAnchor<T> {
295    #[inline]
296    fn from(rc: &Rc<T>) -> Self {
297        RcWeakAnchor(Rc::downgrade(rc))
298    }
299}
300impl<T> From<&RcAnchor<T>> for RcWeakAnchor<T> {
301    #[inline]
302    fn from(rca: &RcAnchor<T>) -> Self {
303        RcWeakAnchor(Rc::downgrade(&rca.0))
304    }
305}
306impl<T> From<&Arc<T>> for ArcWeakAnchor<T> {
307    #[inline]
308    fn from(arc: &Arc<T>) -> Self {
309        ArcWeakAnchor(Arc::downgrade(arc))
310    }
311}
312impl<T> From<&ArcAnchor<T>> for ArcWeakAnchor<T> {
313    #[inline]
314    fn from(ara: &ArcAnchor<T>) -> Self {
315        ArcWeakAnchor(Arc::downgrade(&ara.0))
316    }
317}
318
319// ===== From conversions (recursive strong -> weak) =====
320
321impl<T> From<&RcRecursive<T>> for RcRecursion<T> {
322    #[inline]
323    fn from(rca: &RcRecursive<T>) -> Self {
324        RcRecursion(Rc::downgrade(&rca.0))
325    }
326}
327
328impl<T> From<&ArcRecursive<T>> for ArcRecursion<T> {
329    #[inline]
330    fn from(ara: &ArcRecursive<T>) -> Self {
331        ArcRecursion(Arc::downgrade(&ara.0))
332    }
333}
334
335// ===== Ergonomics: Deref / AsRef / Borrow / Into =====
336
337impl<T> Deref for RcAnchor<T> {
338    type Target = Rc<T>;
339    #[inline]
340    fn deref(&self) -> &Self::Target {
341        &self.0
342    }
343}
344impl<T> Deref for ArcAnchor<T> {
345    type Target = Arc<T>;
346    #[inline]
347    fn deref(&self) -> &Self::Target {
348        &self.0
349    }
350}
351impl<T> Deref for RcRecursive<T> {
352    type Target = Rc<RefCell<Option<T>>>;
353    #[inline]
354    fn deref(&self) -> &Self::Target {
355        &self.0
356    }
357}
358impl<T> Deref for ArcRecursive<T> {
359    type Target = Arc<Mutex<Option<T>>>;
360    #[inline]
361    fn deref(&self) -> &Self::Target {
362        &self.0
363    }
364}
365impl<T> AsRef<Rc<T>> for RcAnchor<T> {
366    #[inline]
367    fn as_ref(&self) -> &Rc<T> {
368        &self.0
369    }
370}
371impl<T> AsRef<Arc<T>> for ArcAnchor<T> {
372    #[inline]
373    fn as_ref(&self) -> &Arc<T> {
374        &self.0
375    }
376}
377impl<T> Borrow<Rc<T>> for RcAnchor<T> {
378    #[inline]
379    fn borrow(&self) -> &Rc<T> {
380        &self.0
381    }
382}
383impl<T> Borrow<Arc<T>> for ArcAnchor<T> {
384    #[inline]
385    fn borrow(&self) -> &Arc<T> {
386        &self.0
387    }
388}
389impl<T> From<RcAnchor<T>> for Rc<T> {
390    #[inline]
391    fn from(a: RcAnchor<T>) -> Rc<T> {
392        a.0
393    }
394}
395impl<T> From<ArcAnchor<T>> for Arc<T> {
396    #[inline]
397    fn from(a: ArcAnchor<T>) -> Arc<T> {
398        a.0
399    }
400}
401
402impl<T> RcRecursive<T> {
403    /// Create a new recursive anchor with an initialized value.
404    #[must_use]
405    pub fn wrapping(x: T) -> Self {
406        RcRecursive(Rc::new(RefCell::new(Some(x))))
407    }
408
409    /// Try to borrow the inner value if the recursive placeholder has been initialized.
410    ///
411    /// Returns [`None`] while a recursive anchor is still being deserialized.
412    #[must_use]
413    pub fn try_borrow_initialized(&self) -> Option<std::cell::Ref<'_, T>> {
414        let borrowed = self.0.as_ref().try_borrow().ok()?;
415        std::cell::Ref::filter_map(borrowed, Option::as_ref).ok()
416    }
417
418    /// Borrow the inner value.
419    ///
420    /// # Panics
421    ///
422    /// Panics if called while a recursive anchor placeholder is still uninitialized.
423    /// Use [`try_borrow_initialized`](Self::try_borrow_initialized) when early access is possible.
424    #[track_caller]
425    pub fn borrow(&self) -> std::cell::Ref<'_, T> {
426        let borrowed = self.0.as_ref().borrow();
427        std::cell::Ref::filter_map(borrowed, Option::as_ref)
428            .ok()
429            .expect("recursive Rc anchor not initialized")
430    }
431}
432
433impl<T> ArcRecursive<T> {
434    /// Create a new recursive anchor with an initialized value.
435    #[must_use]
436    pub fn wrapping(x: T) -> Self {
437        ArcRecursive(Arc::new(Mutex::new(Some(x))))
438    }
439
440    /// Lock the recursive anchor value so that it can be accessed safely.
441    pub fn lock(&self) -> std::sync::LockResult<std::sync::MutexGuard<'_, Option<T>>> {
442        self.0.lock()
443    }
444}
445
446// ===== Weak helpers =====
447
448impl<T> RcWeakAnchor<T> {
449    /// Try to upgrade the weak reference to [`Rc<T>`].
450    /// Returns [`None`] if the value has been dropped.
451    #[inline]
452    #[must_use]
453    pub fn upgrade(&self) -> Option<Rc<T>> {
454        self.0.upgrade()
455    }
456
457    /// Returns `true` if the underlying value has been dropped (no strong refs remain).
458    #[inline]
459    #[must_use]
460    pub fn is_dangling(&self) -> bool {
461        self.0.strong_count() == 0
462    }
463}
464impl<T> RcRecursion<T> {
465    /// Try to upgrade the weak reference to [`RcRecursive<T>`].
466    #[inline]
467    #[must_use]
468    pub fn upgrade(&self) -> Option<RcRecursive<T>> {
469        self.0.upgrade().map(RcRecursive)
470    }
471
472    /// Access the recursive value in one step, if it is still alive.
473    #[inline]
474    pub fn with<R>(&self, f: impl FnOnce(&T) -> R) -> Option<R> {
475        let upgraded = self.upgrade()?;
476        let borrowed = upgraded.try_borrow_initialized()?;
477        Some(f(&borrowed))
478    }
479
480    /// Returns `true` if the underlying value has been dropped (no strong refs remain).
481    #[inline]
482    #[must_use]
483    pub fn is_dangling(&self) -> bool {
484        self.0.strong_count() == 0
485    }
486}
487impl<T> ArcRecursion<T> {
488    /// Try to upgrade the weak reference to [`ArcRecursive<T>`].
489    #[inline]
490    #[must_use]
491    pub fn upgrade(&self) -> Option<ArcRecursive<T>> {
492        self.0.upgrade().map(ArcRecursive)
493    }
494
495    /// Access the recursive value in one step, if it is still alive.
496    #[inline]
497    pub fn with<R>(&self, f: impl FnOnce(&T) -> R) -> Option<R> {
498        let upgraded = self.upgrade()?;
499        let guard = upgraded.lock().ok()?;
500        let value = guard.as_ref()?;
501        Some(f(value))
502    }
503
504    /// Returns `true` if the underlying value has been dropped (no strong refs remain).
505    #[inline]
506    #[must_use]
507    pub fn is_dangling(&self) -> bool {
508        self.0.strong_count() == 0
509    }
510}
511impl<T> ArcWeakAnchor<T> {
512    /// Try to upgrade the weak reference to [`Arc<T>`].
513    /// Returns [`None`] if the value has been dropped.
514    #[inline]
515    #[must_use]
516    pub fn upgrade(&self) -> Option<Arc<T>> {
517        self.0.upgrade()
518    }
519
520    /// Returns `true` if the underlying value has been dropped (no strong refs remain).
521    #[inline]
522    #[must_use]
523    pub fn is_dangling(&self) -> bool {
524        self.0.strong_count() == 0
525    }
526}
527
528// ===== Pointer-equality PartialEq/Eq =====
529
530impl<T> PartialEq for RcAnchor<T> {
531    #[inline]
532    fn eq(&self, other: &Self) -> bool {
533        Rc::ptr_eq(&self.0, &other.0)
534    }
535}
536impl<T> Eq for RcAnchor<T> {}
537
538impl<T> PartialEq for ArcAnchor<T> {
539    #[inline]
540    fn eq(&self, other: &Self) -> bool {
541        Arc::ptr_eq(&self.0, &other.0)
542    }
543}
544impl<T> Eq for ArcAnchor<T> {}
545
546impl<T> PartialEq for RcWeakAnchor<T> {
547    #[inline]
548    fn eq(&self, other: &Self) -> bool {
549        self.0.ptr_eq(&other.0)
550    }
551}
552impl<T> Eq for RcWeakAnchor<T> {}
553
554impl<T> PartialEq for RcRecursion<T> {
555    #[inline]
556    fn eq(&self, other: &Self) -> bool {
557        self.0.ptr_eq(&other.0)
558    }
559}
560impl<T> Eq for RcRecursion<T> {}
561
562impl<T> PartialEq for ArcWeakAnchor<T> {
563    #[inline]
564    fn eq(&self, other: &Self) -> bool {
565        self.0.ptr_eq(&other.0)
566    }
567}
568impl<T> PartialEq for RcRecursive<T> {
569    #[inline]
570    fn eq(&self, other: &Self) -> bool {
571        Rc::ptr_eq(&self.0, &other.0)
572    }
573}
574impl<T> Eq for RcRecursive<T> {}
575
576impl<T> PartialEq for ArcRecursion<T> {
577    #[inline]
578    fn eq(&self, other: &Self) -> bool {
579        self.0.ptr_eq(&other.0)
580    }
581}
582impl<T> Eq for ArcRecursion<T> {}
583
584impl<T> PartialEq for ArcRecursive<T> {
585    #[inline]
586    fn eq(&self, other: &Self) -> bool {
587        Arc::ptr_eq(&self.0, &other.0)
588    }
589}
590impl<T> Eq for ArcRecursive<T> {}
591impl<T> Eq for ArcWeakAnchor<T> {}
592
593// ===== Debug =====
594
595impl<T> fmt::Debug for RcAnchor<T> {
596    #[inline]
597    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
598        write!(f, "RcAnchor({:p})", Rc::as_ptr(&self.0))
599    }
600}
601impl<T> fmt::Debug for ArcAnchor<T> {
602    #[inline]
603    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
604        write!(f, "ArcAnchor({:p})", Arc::as_ptr(&self.0))
605    }
606}
607impl<T> fmt::Debug for RcWeakAnchor<T> {
608    #[inline]
609    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
610        if let Some(rc) = self.0.upgrade() {
611            write!(f, "RcWeakAnchor(upgrade={:p})", Rc::as_ptr(&rc))
612        } else {
613            write!(f, "RcWeakAnchor(dangling)")
614        }
615    }
616}
617impl<T> fmt::Debug for ArcWeakAnchor<T> {
618    #[inline]
619    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
620        if let Some(arc) = self.0.upgrade() {
621            write!(f, "ArcWeakAnchor(upgrade={:p})", Arc::as_ptr(&arc))
622        } else {
623            write!(f, "ArcWeakAnchor(dangling)")
624        }
625    }
626}
627impl<T> fmt::Debug for RcRecursive<T> {
628    #[inline]
629    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
630        write!(f, "RcRecursive({:p})", Rc::as_ptr(&self.0))
631    }
632}
633impl<T> fmt::Debug for ArcRecursive<T> {
634    #[inline]
635    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
636        write!(f, "ArcRecursive({:p})", Arc::as_ptr(&self.0))
637    }
638}
639impl<T> fmt::Debug for RcRecursion<T> {
640    #[inline]
641    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
642        if let Some(rc) = self.0.upgrade() {
643            write!(f, "RcRecursion(upgrade={:p})", Rc::as_ptr(&rc))
644        } else {
645            write!(f, "RcRecursion(dangling)")
646        }
647    }
648}
649impl<T> fmt::Debug for ArcRecursion<T> {
650    #[inline]
651    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
652        if let Some(arc) = self.0.upgrade() {
653            write!(f, "ArcRecursion(upgrade={:p})", Arc::as_ptr(&arc))
654        } else {
655            write!(f, "ArcRecursion(dangling)")
656        }
657    }
658}
659
660// ===== Default =====
661
662impl<T: Default> Default for RcAnchor<T> {
663    #[inline]
664    fn default() -> Self {
665        RcAnchor(Rc::new(T::default()))
666    }
667}
668impl<T: Default> Default for ArcAnchor<T> {
669    fn default() -> Self {
670        ArcAnchor(Arc::new(T::default()))
671    }
672}
673impl<T: Default> Default for RcRecursive<T> {
674    #[inline]
675    fn default() -> Self {
676        RcRecursive(Rc::new(RefCell::new(Some(T::default()))))
677    }
678}
679impl<T: Default> Default for ArcRecursive<T> {
680    fn default() -> Self {
681        ArcRecursive(Arc::new(Mutex::new(Some(T::default()))))
682    }
683}
684
685// -------------------------------
686// Deserialize impls
687// -------------------------------
688#[cfg(feature = "deserialize")]
689impl<'de, T> serde_core::de::Deserialize<'de> for RcAnchor<T>
690where
691    T: serde_core::de::Deserialize<'de> + 'static,
692{
693    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
694    where
695        D: serde_core::de::Deserializer<'de>,
696    {
697        struct RcAnchorVisitor<T>(PhantomData<T>);
698
699        impl<'de, T> Visitor<'de> for RcAnchorVisitor<T>
700        where
701            T: serde_core::de::Deserialize<'de> + 'static,
702        {
703            type Value = RcAnchor<T>;
704
705            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
706                f.write_str("an RcAnchor newtype")
707            }
708
709            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
710            where
711                D: serde_core::de::Deserializer<'de>,
712            {
713                let anchor_id = anchor_store::claim_rc_anchor();
714                let existing = match anchor_id {
715                    Some(id) => {
716                        Some((id, anchor_store::get_rc::<T>(id).map_err(D::Error::custom)?))
717                    }
718                    None => None,
719                };
720                if let Some((id, None)) = existing
721                    && anchor_store::rc_anchor_reentrant(id)
722                {
723                    return Err(D::Error::custom(
724                        "Recursive references require weak anchors",
725                    ));
726                }
727
728                let value = T::deserialize(deserializer)?;
729                if let Some((_, Some(rc))) = existing {
730                    drop(value);
731                    return Ok(RcAnchor(rc));
732                }
733                if let Some((id, None)) = existing {
734                    let rc = Rc::new(value);
735                    anchor_store::store_rc(id, rc.clone());
736                    return Ok(RcAnchor(rc));
737                }
738                Ok(RcAnchor(Rc::new(value)))
739            }
740        }
741
742        deserializer.deserialize_newtype_struct("__yaml_rc_anchor", RcAnchorVisitor(PhantomData))
743    }
744}
745
746#[cfg(feature = "deserialize")]
747impl<'de, T> serde_core::de::Deserialize<'de> for ArcAnchor<T>
748where
749    T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
750{
751    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
752    where
753        D: serde_core::de::Deserializer<'de>,
754    {
755        struct ArcAnchorVisitor<T>(PhantomData<T>);
756
757        impl<'de, T> Visitor<'de> for ArcAnchorVisitor<T>
758        where
759            T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
760        {
761            type Value = ArcAnchor<T>;
762
763            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
764                f.write_str("an ArcAnchor newtype")
765            }
766
767            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
768            where
769                D: serde_core::de::Deserializer<'de>,
770            {
771                let anchor_id = anchor_store::claim_arc_anchor();
772                let existing = match anchor_id {
773                    Some(id) => Some((
774                        id,
775                        anchor_store::get_arc::<T>(id).map_err(D::Error::custom)?,
776                    )),
777                    None => None,
778                };
779                if let Some((id, None)) = existing
780                    && anchor_store::arc_anchor_reentrant(id)
781                {
782                    return Err(D::Error::custom(
783                        "Recursive references require weak anchors",
784                    ));
785                }
786
787                let value = T::deserialize(deserializer)?;
788                if let Some((_, Some(arc))) = existing {
789                    drop(value);
790                    return Ok(ArcAnchor(arc));
791                }
792                if let Some((id, None)) = existing {
793                    let arc = Arc::new(value);
794                    anchor_store::store_arc(id, arc.clone());
795                    return Ok(ArcAnchor(arc));
796                }
797                Ok(ArcAnchor(Arc::new(value)))
798            }
799        }
800
801        deserializer.deserialize_newtype_struct("__yaml_arc_anchor", ArcAnchorVisitor(PhantomData))
802    }
803}
804
805#[cfg(feature = "deserialize")]
806impl<'de, T> serde_core::de::Deserialize<'de> for RcRecursive<T>
807where
808    T: serde_core::de::Deserialize<'de> + 'static,
809{
810    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
811    where
812        D: serde_core::de::Deserializer<'de>,
813    {
814        struct RcRecursiveVisitor<T>(PhantomData<T>);
815
816        impl<'de, T> Visitor<'de> for RcRecursiveVisitor<T>
817        where
818            T: serde_core::de::Deserialize<'de> + 'static,
819        {
820            type Value = RcRecursive<T>;
821
822            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
823                f.write_str("an RcRecursive newtype")
824            }
825
826            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
827            where
828                D: serde_core::de::Deserializer<'de>,
829            {
830                let anchor_id = anchor_store::claim_rc_recursive_anchor();
831                let existing = match anchor_id {
832                    Some(id) => Some((
833                        id,
834                        anchor_store::get_rc_recursive::<RefCell<Option<T>>>(id)
835                            .map_err(D::Error::custom)?,
836                    )),
837                    None => None,
838                };
839                if let Some((id, None)) = existing
840                    && anchor_store::rc_recursive_reentrant(id)
841                {
842                    return Err(D::Error::custom(
843                        "recursive references require weak recursion types",
844                    ));
845                }
846
847                if let Some((_, Some(rc))) = existing {
848                    let value = T::deserialize(deserializer)?;
849                    drop(value);
850                    return Ok(RcRecursive(rc));
851                }
852
853                if let Some((id, None)) = existing {
854                    let rc = Rc::new(RefCell::new(None));
855                    anchor_store::store_rc_recursive(id, rc.clone());
856
857                    let value = T::deserialize(deserializer)?;
858                    *rc.borrow_mut() = Some(value);
859                    return Ok(RcRecursive(rc));
860                }
861
862                let value = T::deserialize(deserializer)?;
863                Ok(RcRecursive(Rc::new(RefCell::new(Some(value)))))
864            }
865        }
866
867        deserializer
868            .deserialize_newtype_struct("__yaml_rc_recursive", RcRecursiveVisitor(PhantomData))
869    }
870}
871
872#[cfg(feature = "deserialize")]
873impl<'de, T> serde_core::de::Deserialize<'de> for ArcRecursive<T>
874where
875    T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
876{
877    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
878    where
879        D: serde_core::de::Deserializer<'de>,
880    {
881        struct ArcRecursiveVisitor<T>(PhantomData<T>);
882
883        impl<'de, T> Visitor<'de> for ArcRecursiveVisitor<T>
884        where
885            T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
886        {
887            type Value = ArcRecursive<T>;
888
889            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
890                f.write_str("an ArcRecursive newtype")
891            }
892
893            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
894            where
895                D: serde_core::de::Deserializer<'de>,
896            {
897                let anchor_id = anchor_store::claim_arc_recursive_anchor();
898                let existing = match anchor_id {
899                    Some(id) => Some((
900                        id,
901                        anchor_store::get_arc_recursive::<Mutex<Option<T>>>(id)
902                            .map_err(D::Error::custom)?,
903                    )),
904                    None => None,
905                };
906                if let Some((id, None)) = existing
907                    && anchor_store::arc_recursive_reentrant(id)
908                {
909                    return Err(D::Error::custom(
910                        "recursive references require weak recursion types",
911                    ));
912                }
913
914                if let Some((_, Some(arc))) = existing {
915                    let value = T::deserialize(deserializer)?;
916                    drop(value);
917                    return Ok(ArcRecursive(arc));
918                }
919
920                if let Some((id, None)) = existing {
921                    let arc = Arc::new(Mutex::new(None));
922                    anchor_store::store_arc_recursive(id, arc.clone());
923
924                    let value = T::deserialize(deserializer)?;
925                    *arc.lock()
926                        .map_err(|_| D::Error::custom("recursive Arc anchor mutex poisoned"))? =
927                        Some(value);
928                    return Ok(ArcRecursive(arc));
929                }
930
931                let value = T::deserialize(deserializer)?;
932                Ok(ArcRecursive(Arc::new(Mutex::new(Some(value)))))
933            }
934        }
935
936        deserializer
937            .deserialize_newtype_struct("__yaml_arc_recursive", ArcRecursiveVisitor(PhantomData))
938    }
939}
940
941// -------------------------------
942// Deserialize impls for WEAK anchors (RcWeakAnchor / ArcWeakAnchor)
943// -------------------------------
944#[cfg(feature = "deserialize")]
945impl<'de, T> serde_core::de::Deserialize<'de> for RcWeakAnchor<T>
946where
947    T: serde_core::de::Deserialize<'de> + 'static,
948{
949    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
950    where
951        D: serde_core::de::Deserializer<'de>,
952    {
953        struct RcWeakVisitor<T>(PhantomData<T>);
954        impl<'de, T> Visitor<'de> for RcWeakVisitor<T>
955        where
956            T: serde_core::de::Deserialize<'de> + 'static,
957        {
958            type Value = RcWeakAnchor<T>;
959            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
960                f.write_str(
961                    "an RcWeakAnchor referring to a previously defined strong anchor (via alias)",
962                )
963            }
964            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
965            where
966                D: serde_core::de::Deserializer<'de>,
967            {
968                // `null` is the serialization form for dangling weak refs.
969                let is_null =
970                    <Option<serde_core::de::IgnoredAny> as serde_core::de::Deserialize>::deserialize(
971                        deserializer,
972                    )?
973                    .is_none();
974                if is_null {
975                    return Ok(RcWeakAnchor(RcWeak::new()));
976                }
977
978                // Anchor context is established by the deserializer when the special name is used.
979                let id = anchor_store::current_rc_anchor().ok_or_else(|| {
980                    D::Error::custom(
981                        "weak Rc anchor must refer to an existing strong anchor via alias",
982                    )
983                })?;
984                // Look up the strong reference by id and downgrade.
985                match anchor_store::get_rc::<T>(id).map_err(D::Error::custom)? {
986                    Some(rc) => Ok(RcWeakAnchor(Rc::downgrade(&rc))),
987                    None if anchor_store::rc_anchor_reentrant(id) => {
988                        Err(D::Error::custom("Recursive references require RcRecursion"))
989                    }
990                    None => Err(D::Error::custom(
991                        "weak Rc anchor refers to unknown anchor; strong anchor must be defined before weak",
992                    )),
993                }
994            }
995        }
996        deserializer.deserialize_newtype_struct("__yaml_rc_weak_anchor", RcWeakVisitor(PhantomData))
997    }
998}
999
1000#[cfg(feature = "deserialize")]
1001impl<'de, T> serde_core::de::Deserialize<'de> for ArcWeakAnchor<T>
1002where
1003    T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
1004{
1005    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1006    where
1007        D: serde_core::de::Deserializer<'de>,
1008    {
1009        struct ArcWeakVisitor<T>(PhantomData<T>);
1010        impl<'de, T> Visitor<'de> for ArcWeakVisitor<T>
1011        where
1012            T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
1013        {
1014            type Value = ArcWeakAnchor<T>;
1015            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1016                f.write_str(
1017                    "an ArcWeakAnchor referring to a previously defined strong anchor (via alias)",
1018                )
1019            }
1020            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
1021            where
1022                D: serde_core::de::Deserializer<'de>,
1023            {
1024                let is_null =
1025                    <Option<serde_core::de::IgnoredAny> as serde_core::de::Deserialize>::deserialize(
1026                        deserializer,
1027                    )?
1028                    .is_none();
1029                if is_null {
1030                    return Ok(ArcWeakAnchor(ArcWeak::new()));
1031                }
1032
1033                let id = anchor_store::current_arc_anchor().ok_or_else(|| {
1034                    D::Error::custom(
1035                        "weak Arc anchor must refer to an existing strong anchor via alias",
1036                    )
1037                })?;
1038                match anchor_store::get_arc::<T>(id).map_err(D::Error::custom)? {
1039                    Some(arc) => Ok(ArcWeakAnchor(Arc::downgrade(&arc))),
1040                    None if anchor_store::arc_anchor_reentrant(id) => Err(D::Error::custom(
1041                        "Recursive references require ArcRecursion",
1042                    )),
1043                    None => Err(D::Error::custom(
1044                        "weak Arc anchor refers to unknown anchor; strong anchor must be defined before weak",
1045                    )),
1046                }
1047            }
1048        }
1049        deserializer
1050            .deserialize_newtype_struct("__yaml_arc_weak_anchor", ArcWeakVisitor(PhantomData))
1051    }
1052}
1053
1054#[cfg(feature = "deserialize")]
1055impl<'de, T> serde_core::de::Deserialize<'de> for RcRecursion<T>
1056where
1057    T: serde_core::de::Deserialize<'de> + 'static,
1058{
1059    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1060    where
1061        D: serde_core::de::Deserializer<'de>,
1062    {
1063        struct RcRecursionVisitor<T>(PhantomData<T>);
1064        impl<'de, T> Visitor<'de> for RcRecursionVisitor<T>
1065        where
1066            T: serde_core::de::Deserialize<'de> + 'static,
1067        {
1068            type Value = RcRecursion<T>;
1069            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1070                f.write_str(
1071                    "an RcRecursion referring to a previously defined recursive strong anchor (via alias)",
1072                )
1073            }
1074            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
1075            where
1076                D: serde_core::de::Deserializer<'de>,
1077            {
1078                let id = anchor_store::current_rc_recursive_anchor().ok_or_else(|| {
1079                    D::Error::custom(
1080                        "RcRecursion must refer to an existing recursive strong anchor via alias",
1081                    )
1082                })?;
1083                let _ = <serde_core::de::IgnoredAny as serde_core::de::Deserialize>::deserialize(
1084                    deserializer,
1085                )?;
1086                match anchor_store::get_rc_recursive::<RefCell<Option<T>>>(id)
1087                    .map_err(D::Error::custom)?
1088                {
1089                    Some(rc) => Ok(RcRecursion(Rc::downgrade(&rc))),
1090                    None => Err(D::Error::custom(
1091                        "RcRecursion refers to unknown recursive anchor id",
1092                    )),
1093                }
1094            }
1095        }
1096        deserializer
1097            .deserialize_newtype_struct("__yaml_rc_recursion", RcRecursionVisitor(PhantomData))
1098    }
1099}
1100
1101#[cfg(feature = "deserialize")]
1102impl<'de, T> serde_core::de::Deserialize<'de> for ArcRecursion<T>
1103where
1104    T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
1105{
1106    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1107    where
1108        D: serde_core::de::Deserializer<'de>,
1109    {
1110        struct ArcRecursionVisitor<T>(PhantomData<T>);
1111        impl<'de, T> Visitor<'de> for ArcRecursionVisitor<T>
1112        where
1113            T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
1114        {
1115            type Value = ArcRecursion<T>;
1116            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1117                f.write_str(
1118                    "an ArcRecursion referring to a previously defined recursive strong anchor (via alias)",
1119                )
1120            }
1121            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
1122            where
1123                D: serde_core::de::Deserializer<'de>,
1124            {
1125                let id = anchor_store::current_arc_recursive_anchor().ok_or_else(|| {
1126                    D::Error::custom(
1127                        "ArcRecursion must refer to an existing recursive strong anchor via alias",
1128                    )
1129                })?;
1130                let _ = <serde_core::de::IgnoredAny as serde_core::de::Deserialize>::deserialize(
1131                    deserializer,
1132                )?;
1133                match anchor_store::get_arc_recursive::<Mutex<Option<T>>>(id)
1134                    .map_err(D::Error::custom)?
1135                {
1136                    Some(arc) => Ok(ArcRecursion(Arc::downgrade(&arc))),
1137                    None => Err(D::Error::custom(
1138                        "ArcRecursion refers to unknown recursive anchor id",
1139                    )),
1140                }
1141            }
1142        }
1143        deserializer
1144            .deserialize_newtype_struct("__yaml_arc_recursion", ArcRecursionVisitor(PhantomData))
1145    }
1146}