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    /// Create inner Rc (takes arbitrary value Rc can take)
271    pub fn wrapping(x: T) -> Self {
272        RcAnchor(Rc::new(x))
273    }
274}
275
276impl<T> ArcAnchor<T> {
277    /// Create inner Arc (takes arbitrary value Arc can take)
278    pub fn wrapping(x: T) -> Self {
279        ArcAnchor(Arc::new(x))
280    }
281}
282
283impl<T> From<Arc<T>> for ArcAnchor<T> {
284    #[inline]
285    fn from(arc: Arc<T>) -> Self {
286        ArcAnchor(arc)
287    }
288}
289
290// ===== From conversions (strong -> weak anchor) =====
291
292impl<T> From<&Rc<T>> for RcWeakAnchor<T> {
293    #[inline]
294    fn from(rc: &Rc<T>) -> Self {
295        RcWeakAnchor(Rc::downgrade(rc))
296    }
297}
298impl<T> From<Rc<T>> for RcWeakAnchor<T> {
299    #[inline]
300    fn from(rc: Rc<T>) -> Self {
301        RcWeakAnchor(Rc::downgrade(&rc))
302    }
303}
304impl<T> From<&RcAnchor<T>> for RcWeakAnchor<T> {
305    #[inline]
306    fn from(rca: &RcAnchor<T>) -> Self {
307        RcWeakAnchor(Rc::downgrade(&rca.0))
308    }
309}
310impl<T> From<&Arc<T>> for ArcWeakAnchor<T> {
311    #[inline]
312    fn from(arc: &Arc<T>) -> Self {
313        ArcWeakAnchor(Arc::downgrade(arc))
314    }
315}
316impl<T> From<Arc<T>> for ArcWeakAnchor<T> {
317    #[inline]
318    fn from(arc: Arc<T>) -> Self {
319        ArcWeakAnchor(Arc::downgrade(&arc))
320    }
321}
322impl<T> From<&ArcAnchor<T>> for ArcWeakAnchor<T> {
323    #[inline]
324    fn from(ara: &ArcAnchor<T>) -> Self {
325        ArcWeakAnchor(Arc::downgrade(&ara.0))
326    }
327}
328
329// ===== From conversions (recursive strong -> weak) =====
330
331impl<T> From<&RcRecursive<T>> for RcRecursion<T> {
332    #[inline]
333    fn from(rca: &RcRecursive<T>) -> Self {
334        RcRecursion(Rc::downgrade(&rca.0))
335    }
336}
337
338impl<T> From<&ArcRecursive<T>> for ArcRecursion<T> {
339    #[inline]
340    fn from(ara: &ArcRecursive<T>) -> Self {
341        ArcRecursion(Arc::downgrade(&ara.0))
342    }
343}
344
345// ===== Ergonomics: Deref / AsRef / Borrow / Into =====
346
347impl<T> Deref for RcAnchor<T> {
348    type Target = Rc<T>;
349    #[inline]
350    fn deref(&self) -> &Self::Target {
351        &self.0
352    }
353}
354impl<T> Deref for ArcAnchor<T> {
355    type Target = Arc<T>;
356    #[inline]
357    fn deref(&self) -> &Self::Target {
358        &self.0
359    }
360}
361impl<T> Deref for RcRecursive<T> {
362    type Target = Rc<RefCell<Option<T>>>;
363    #[inline]
364    fn deref(&self) -> &Self::Target {
365        &self.0
366    }
367}
368impl<T> Deref for ArcRecursive<T> {
369    type Target = Arc<Mutex<Option<T>>>;
370    #[inline]
371    fn deref(&self) -> &Self::Target {
372        &self.0
373    }
374}
375impl<T> AsRef<Rc<T>> for RcAnchor<T> {
376    #[inline]
377    fn as_ref(&self) -> &Rc<T> {
378        &self.0
379    }
380}
381impl<T> AsRef<Arc<T>> for ArcAnchor<T> {
382    #[inline]
383    fn as_ref(&self) -> &Arc<T> {
384        &self.0
385    }
386}
387impl<T> Borrow<Rc<T>> for RcAnchor<T> {
388    #[inline]
389    fn borrow(&self) -> &Rc<T> {
390        &self.0
391    }
392}
393impl<T> Borrow<Arc<T>> for ArcAnchor<T> {
394    #[inline]
395    fn borrow(&self) -> &Arc<T> {
396        &self.0
397    }
398}
399impl<T> From<RcAnchor<T>> for Rc<T> {
400    #[inline]
401    fn from(a: RcAnchor<T>) -> Rc<T> {
402        a.0
403    }
404}
405impl<T> From<ArcAnchor<T>> for Arc<T> {
406    #[inline]
407    fn from(a: ArcAnchor<T>) -> Arc<T> {
408        a.0
409    }
410}
411
412impl<T> RcRecursive<T> {
413    /// Create a new recursive anchor with an initialized value.
414    pub fn wrapping(x: T) -> Self {
415        RcRecursive(Rc::new(RefCell::new(Some(x))))
416    }
417
418    /// Try to borrow the inner value if the recursive placeholder has been initialized.
419    ///
420    /// Returns [`None`] while a recursive anchor is still being deserialized.
421    pub fn try_borrow_initialized(&self) -> Option<std::cell::Ref<'_, T>> {
422        let borrowed = self.0.as_ref().try_borrow().ok()?;
423        std::cell::Ref::filter_map(borrowed, Option::as_ref).ok()
424    }
425
426    /// Borrow the inner value.
427    ///
428    /// # Panics
429    ///
430    /// Panics if called while a recursive anchor placeholder is still uninitialized.
431    /// Use [`try_borrow_initialized`](Self::try_borrow_initialized) when early access is possible.
432    pub fn borrow(&self) -> std::cell::Ref<'_, T> {
433        let borrowed = self.0.as_ref().borrow();
434        std::cell::Ref::filter_map(borrowed, Option::as_ref)
435            .ok()
436            .expect("recursive Rc anchor not initialized")
437    }
438}
439
440impl<T> ArcRecursive<T> {
441    /// Create a new recursive anchor with an initialized value.
442    pub fn wrapping(x: T) -> Self {
443        ArcRecursive(Arc::new(Mutex::new(Some(x))))
444    }
445
446    /// Lock the recursive anchor value so that it can be accessed safely.
447    pub fn lock(&self) -> std::sync::LockResult<std::sync::MutexGuard<'_, Option<T>>> {
448        self.0.lock()
449    }
450}
451
452// ===== Weak helpers =====
453
454impl<T> RcWeakAnchor<T> {
455    /// Try to upgrade the weak reference to [`Rc<T>`].
456    /// Returns [`None`] if the value has been dropped.
457    #[inline]
458    pub fn upgrade(&self) -> Option<Rc<T>> {
459        self.0.upgrade()
460    }
461
462    /// Returns `true` if the underlying value has been dropped (no strong refs remain).
463    #[inline]
464    pub fn is_dangling(&self) -> bool {
465        self.0.strong_count() == 0
466    }
467}
468impl<T> RcRecursion<T> {
469    /// Try to upgrade the weak reference to [`RcRecursive<T>`].
470    #[inline]
471    pub fn upgrade(&self) -> Option<RcRecursive<T>> {
472        self.0.upgrade().map(RcRecursive)
473    }
474
475    /// Access the recursive value in one step, if it is still alive.
476    #[inline]
477    pub fn with<R>(&self, f: impl FnOnce(&T) -> R) -> Option<R> {
478        let upgraded = self.upgrade()?;
479        let borrowed = upgraded.try_borrow_initialized()?;
480        Some(f(&borrowed))
481    }
482
483    /// Returns `true` if the underlying value has been dropped (no strong refs remain).
484    #[inline]
485    pub fn is_dangling(&self) -> bool {
486        self.0.strong_count() == 0
487    }
488}
489impl<T> ArcRecursion<T> {
490    /// Try to upgrade the weak reference to [`ArcRecursive<T>`].
491    #[inline]
492    pub fn upgrade(&self) -> Option<ArcRecursive<T>> {
493        self.0.upgrade().map(ArcRecursive)
494    }
495
496    /// Access the recursive value in one step, if it is still alive.
497    #[inline]
498    pub fn with<R>(&self, f: impl FnOnce(&T) -> R) -> Option<R> {
499        let upgraded = self.upgrade()?;
500        let guard = upgraded.lock().ok()?;
501        let value = guard.as_ref()?;
502        Some(f(value))
503    }
504
505    /// Returns `true` if the underlying value has been dropped (no strong refs remain).
506    #[inline]
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    pub fn upgrade(&self) -> Option<Arc<T>> {
516        self.0.upgrade()
517    }
518
519    /// Returns `true` if the underlying value has been dropped (no strong refs remain).
520    #[inline]
521    pub fn is_dangling(&self) -> bool {
522        self.0.strong_count() == 0
523    }
524}
525
526// ===== Pointer-equality PartialEq/Eq =====
527
528impl<T> PartialEq for RcAnchor<T> {
529    #[inline]
530    fn eq(&self, other: &Self) -> bool {
531        Rc::ptr_eq(&self.0, &other.0)
532    }
533}
534impl<T> Eq for RcAnchor<T> {}
535
536impl<T> PartialEq for ArcAnchor<T> {
537    #[inline]
538    fn eq(&self, other: &Self) -> bool {
539        Arc::ptr_eq(&self.0, &other.0)
540    }
541}
542impl<T> Eq for ArcAnchor<T> {}
543
544impl<T> PartialEq for RcWeakAnchor<T> {
545    #[inline]
546    fn eq(&self, other: &Self) -> bool {
547        self.0.ptr_eq(&other.0)
548    }
549}
550impl<T> Eq for RcWeakAnchor<T> {}
551
552impl<T> PartialEq for RcRecursion<T> {
553    #[inline]
554    fn eq(&self, other: &Self) -> bool {
555        self.0.ptr_eq(&other.0)
556    }
557}
558impl<T> Eq for RcRecursion<T> {}
559
560impl<T> PartialEq for ArcWeakAnchor<T> {
561    #[inline]
562    fn eq(&self, other: &Self) -> bool {
563        self.0.ptr_eq(&other.0)
564    }
565}
566impl<T> PartialEq for RcRecursive<T> {
567    #[inline]
568    fn eq(&self, other: &Self) -> bool {
569        Rc::ptr_eq(&self.0, &other.0)
570    }
571}
572impl<T> Eq for RcRecursive<T> {}
573
574impl<T> PartialEq for ArcRecursion<T> {
575    #[inline]
576    fn eq(&self, other: &Self) -> bool {
577        self.0.ptr_eq(&other.0)
578    }
579}
580impl<T> Eq for ArcRecursion<T> {}
581
582impl<T> PartialEq for ArcRecursive<T> {
583    #[inline]
584    fn eq(&self, other: &Self) -> bool {
585        Arc::ptr_eq(&self.0, &other.0)
586    }
587}
588impl<T> Eq for ArcRecursive<T> {}
589impl<T> Eq for ArcWeakAnchor<T> {}
590
591// ===== Debug =====
592
593impl<T> fmt::Debug for RcAnchor<T> {
594    #[inline]
595    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
596        write!(f, "RcAnchor({:p})", Rc::as_ptr(&self.0))
597    }
598}
599impl<T> fmt::Debug for ArcAnchor<T> {
600    #[inline]
601    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
602        write!(f, "ArcAnchor({:p})", Arc::as_ptr(&self.0))
603    }
604}
605impl<T> fmt::Debug for RcWeakAnchor<T> {
606    #[inline]
607    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
608        if let Some(rc) = self.0.upgrade() {
609            write!(f, "RcWeakAnchor(upgrade={:p})", Rc::as_ptr(&rc))
610        } else {
611            write!(f, "RcWeakAnchor(dangling)")
612        }
613    }
614}
615impl<T> fmt::Debug for ArcWeakAnchor<T> {
616    #[inline]
617    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
618        if let Some(arc) = self.0.upgrade() {
619            write!(f, "ArcWeakAnchor(upgrade={:p})", Arc::as_ptr(&arc))
620        } else {
621            write!(f, "ArcWeakAnchor(dangling)")
622        }
623    }
624}
625impl<T> fmt::Debug for RcRecursive<T> {
626    #[inline]
627    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
628        write!(f, "RcRecursive({:p})", Rc::as_ptr(&self.0))
629    }
630}
631impl<T> fmt::Debug for ArcRecursive<T> {
632    #[inline]
633    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
634        write!(f, "ArcRecursive({:p})", Arc::as_ptr(&self.0))
635    }
636}
637impl<T> fmt::Debug for RcRecursion<T> {
638    #[inline]
639    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
640        if let Some(rc) = self.0.upgrade() {
641            write!(f, "RcRecursion(upgrade={:p})", Rc::as_ptr(&rc))
642        } else {
643            write!(f, "RcRecursion(dangling)")
644        }
645    }
646}
647impl<T> fmt::Debug for ArcRecursion<T> {
648    #[inline]
649    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
650        if let Some(arc) = self.0.upgrade() {
651            write!(f, "ArcRecursion(upgrade={:p})", Arc::as_ptr(&arc))
652        } else {
653            write!(f, "ArcRecursion(dangling)")
654        }
655    }
656}
657
658// ===== Default =====
659
660impl<T: Default> Default for RcAnchor<T> {
661    #[inline]
662    fn default() -> Self {
663        RcAnchor(Rc::new(T::default()))
664    }
665}
666impl<T: Default> Default for ArcAnchor<T> {
667    fn default() -> Self {
668        ArcAnchor(Arc::new(T::default()))
669    }
670}
671impl<T: Default> Default for RcRecursive<T> {
672    #[inline]
673    fn default() -> Self {
674        RcRecursive(Rc::new(RefCell::new(Some(T::default()))))
675    }
676}
677impl<T: Default> Default for ArcRecursive<T> {
678    fn default() -> Self {
679        ArcRecursive(Arc::new(Mutex::new(Some(T::default()))))
680    }
681}
682
683// -------------------------------
684// Deserialize impls
685// -------------------------------
686#[cfg(feature = "deserialize")]
687impl<'de, T> serde_core::de::Deserialize<'de> for RcAnchor<T>
688where
689    T: serde_core::de::Deserialize<'de> + 'static,
690{
691    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
692    where
693        D: serde_core::de::Deserializer<'de>,
694    {
695        struct RcAnchorVisitor<T>(PhantomData<T>);
696
697        impl<'de, T> Visitor<'de> for RcAnchorVisitor<T>
698        where
699            T: serde_core::de::Deserialize<'de> + 'static,
700        {
701            type Value = RcAnchor<T>;
702
703            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
704                f.write_str("an RcAnchor newtype")
705            }
706
707            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
708            where
709                D: serde_core::de::Deserializer<'de>,
710            {
711                let anchor_id = anchor_store::claim_rc_anchor();
712                let existing = match anchor_id {
713                    Some(id) => {
714                        Some((id, anchor_store::get_rc::<T>(id).map_err(D::Error::custom)?))
715                    }
716                    None => None,
717                };
718                if let Some((id, None)) = existing
719                    && anchor_store::rc_anchor_reentrant(id)
720                {
721                    return Err(D::Error::custom(
722                        "Recursive references require weak anchors",
723                    ));
724                }
725
726                let value = T::deserialize(deserializer)?;
727                if let Some((_, Some(rc))) = existing {
728                    drop(value);
729                    return Ok(RcAnchor(rc));
730                }
731                if let Some((id, None)) = existing {
732                    let rc = Rc::new(value);
733                    anchor_store::store_rc(id, rc.clone());
734                    return Ok(RcAnchor(rc));
735                }
736                Ok(RcAnchor(Rc::new(value)))
737            }
738        }
739
740        deserializer.deserialize_newtype_struct("__yaml_rc_anchor", RcAnchorVisitor(PhantomData))
741    }
742}
743
744#[cfg(feature = "deserialize")]
745impl<'de, T> serde_core::de::Deserialize<'de> for ArcAnchor<T>
746where
747    T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
748{
749    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
750    where
751        D: serde_core::de::Deserializer<'de>,
752    {
753        struct ArcAnchorVisitor<T>(PhantomData<T>);
754
755        impl<'de, T> Visitor<'de> for ArcAnchorVisitor<T>
756        where
757            T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
758        {
759            type Value = ArcAnchor<T>;
760
761            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
762                f.write_str("an ArcAnchor newtype")
763            }
764
765            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
766            where
767                D: serde_core::de::Deserializer<'de>,
768            {
769                let anchor_id = anchor_store::claim_arc_anchor();
770                let existing = match anchor_id {
771                    Some(id) => Some((
772                        id,
773                        anchor_store::get_arc::<T>(id).map_err(D::Error::custom)?,
774                    )),
775                    None => None,
776                };
777                if let Some((id, None)) = existing
778                    && anchor_store::arc_anchor_reentrant(id)
779                {
780                    return Err(D::Error::custom(
781                        "Recursive references require weak anchors",
782                    ));
783                }
784
785                let value = T::deserialize(deserializer)?;
786                if let Some((_, Some(arc))) = existing {
787                    drop(value);
788                    return Ok(ArcAnchor(arc));
789                }
790                if let Some((id, None)) = existing {
791                    let arc = Arc::new(value);
792                    anchor_store::store_arc(id, arc.clone());
793                    return Ok(ArcAnchor(arc));
794                }
795                Ok(ArcAnchor(Arc::new(value)))
796            }
797        }
798
799        deserializer.deserialize_newtype_struct("__yaml_arc_anchor", ArcAnchorVisitor(PhantomData))
800    }
801}
802
803#[cfg(feature = "deserialize")]
804impl<'de, T> serde_core::de::Deserialize<'de> for RcRecursive<T>
805where
806    T: serde_core::de::Deserialize<'de> + 'static,
807{
808    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
809    where
810        D: serde_core::de::Deserializer<'de>,
811    {
812        struct RcRecursiveVisitor<T>(PhantomData<T>);
813
814        impl<'de, T> Visitor<'de> for RcRecursiveVisitor<T>
815        where
816            T: serde_core::de::Deserialize<'de> + 'static,
817        {
818            type Value = RcRecursive<T>;
819
820            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
821                f.write_str("an RcRecursive newtype")
822            }
823
824            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
825            where
826                D: serde_core::de::Deserializer<'de>,
827            {
828                let anchor_id = anchor_store::claim_rc_recursive_anchor();
829                let existing = match anchor_id {
830                    Some(id) => Some((
831                        id,
832                        anchor_store::get_rc_recursive::<RefCell<Option<T>>>(id)
833                            .map_err(D::Error::custom)?,
834                    )),
835                    None => None,
836                };
837                if let Some((id, None)) = existing
838                    && anchor_store::rc_recursive_reentrant(id)
839                {
840                    return Err(D::Error::custom(
841                        "recursive references require weak recursion types",
842                    ));
843                }
844
845                if let Some((_, Some(rc))) = existing {
846                    let value = T::deserialize(deserializer)?;
847                    drop(value);
848                    return Ok(RcRecursive(rc));
849                }
850
851                if let Some((id, None)) = existing {
852                    let rc = Rc::new(RefCell::new(None));
853                    anchor_store::store_rc_recursive(id, rc.clone());
854
855                    let value = T::deserialize(deserializer)?;
856                    *rc.borrow_mut() = Some(value);
857                    return Ok(RcRecursive(rc));
858                }
859
860                let value = T::deserialize(deserializer)?;
861                Ok(RcRecursive(Rc::new(RefCell::new(Some(value)))))
862            }
863        }
864
865        deserializer
866            .deserialize_newtype_struct("__yaml_rc_recursive", RcRecursiveVisitor(PhantomData))
867    }
868}
869
870#[cfg(feature = "deserialize")]
871impl<'de, T> serde_core::de::Deserialize<'de> for ArcRecursive<T>
872where
873    T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
874{
875    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
876    where
877        D: serde_core::de::Deserializer<'de>,
878    {
879        struct ArcRecursiveVisitor<T>(PhantomData<T>);
880
881        impl<'de, T> Visitor<'de> for ArcRecursiveVisitor<T>
882        where
883            T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
884        {
885            type Value = ArcRecursive<T>;
886
887            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
888                f.write_str("an ArcRecursive newtype")
889            }
890
891            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
892            where
893                D: serde_core::de::Deserializer<'de>,
894            {
895                let anchor_id = anchor_store::claim_arc_recursive_anchor();
896                let existing = match anchor_id {
897                    Some(id) => Some((
898                        id,
899                        anchor_store::get_arc_recursive::<Mutex<Option<T>>>(id)
900                            .map_err(D::Error::custom)?,
901                    )),
902                    None => None,
903                };
904                if let Some((id, None)) = existing
905                    && anchor_store::arc_recursive_reentrant(id)
906                {
907                    return Err(D::Error::custom(
908                        "recursive references require weak recursion types",
909                    ));
910                }
911
912                if let Some((_, Some(arc))) = existing {
913                    let value = T::deserialize(deserializer)?;
914                    drop(value);
915                    return Ok(ArcRecursive(arc));
916                }
917
918                if let Some((id, None)) = existing {
919                    let arc = Arc::new(Mutex::new(None));
920                    anchor_store::store_arc_recursive(id, arc.clone());
921
922                    let value = T::deserialize(deserializer)?;
923                    *arc.lock()
924                        .map_err(|_| D::Error::custom("recursive Arc anchor mutex poisoned"))? =
925                        Some(value);
926                    return Ok(ArcRecursive(arc));
927                }
928
929                let value = T::deserialize(deserializer)?;
930                Ok(ArcRecursive(Arc::new(Mutex::new(Some(value)))))
931            }
932        }
933
934        deserializer
935            .deserialize_newtype_struct("__yaml_arc_recursive", ArcRecursiveVisitor(PhantomData))
936    }
937}
938
939// -------------------------------
940// Deserialize impls for WEAK anchors (RcWeakAnchor / ArcWeakAnchor)
941// -------------------------------
942#[cfg(feature = "deserialize")]
943impl<'de, T> serde_core::de::Deserialize<'de> for RcWeakAnchor<T>
944where
945    T: serde_core::de::Deserialize<'de> + 'static,
946{
947    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
948    where
949        D: serde_core::de::Deserializer<'de>,
950    {
951        struct RcWeakVisitor<T>(PhantomData<T>);
952        impl<'de, T> Visitor<'de> for RcWeakVisitor<T>
953        where
954            T: serde_core::de::Deserialize<'de> + 'static,
955        {
956            type Value = RcWeakAnchor<T>;
957            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
958                f.write_str(
959                    "an RcWeakAnchor referring to a previously defined strong anchor (via alias)",
960                )
961            }
962            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
963            where
964                D: serde_core::de::Deserializer<'de>,
965            {
966                // `null` is the serialization form for dangling weak refs.
967                let is_null =
968                    <Option<serde_core::de::IgnoredAny> as serde_core::de::Deserialize>::deserialize(
969                        deserializer,
970                    )?
971                    .is_none();
972                if is_null {
973                    return Ok(RcWeakAnchor(RcWeak::new()));
974                }
975
976                // Anchor context is established by the deserializer when the special name is used.
977                let id = anchor_store::current_rc_anchor().ok_or_else(|| {
978                    D::Error::custom(
979                        "weak Rc anchor must refer to an existing strong anchor via alias",
980                    )
981                })?;
982                // Look up the strong reference by id and downgrade.
983                match anchor_store::get_rc::<T>(id).map_err(D::Error::custom)? {
984                    Some(rc) => Ok(RcWeakAnchor(Rc::downgrade(&rc))),
985                    None if anchor_store::rc_anchor_reentrant(id) => {
986                        Err(D::Error::custom("Recursive references require RcRecursion"))
987                    }
988                    None => Err(D::Error::custom(
989                        "weak Rc anchor refers to unknown anchor; strong anchor must be defined before weak",
990                    )),
991                }
992            }
993        }
994        deserializer.deserialize_newtype_struct("__yaml_rc_weak_anchor", RcWeakVisitor(PhantomData))
995    }
996}
997
998#[cfg(feature = "deserialize")]
999impl<'de, T> serde_core::de::Deserialize<'de> for ArcWeakAnchor<T>
1000where
1001    T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
1002{
1003    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1004    where
1005        D: serde_core::de::Deserializer<'de>,
1006    {
1007        struct ArcWeakVisitor<T>(PhantomData<T>);
1008        impl<'de, T> Visitor<'de> for ArcWeakVisitor<T>
1009        where
1010            T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
1011        {
1012            type Value = ArcWeakAnchor<T>;
1013            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1014                f.write_str(
1015                    "an ArcWeakAnchor referring to a previously defined strong anchor (via alias)",
1016                )
1017            }
1018            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
1019            where
1020                D: serde_core::de::Deserializer<'de>,
1021            {
1022                let is_null =
1023                    <Option<serde_core::de::IgnoredAny> as serde_core::de::Deserialize>::deserialize(
1024                        deserializer,
1025                    )?
1026                    .is_none();
1027                if is_null {
1028                    return Ok(ArcWeakAnchor(ArcWeak::new()));
1029                }
1030
1031                let id = anchor_store::current_arc_anchor().ok_or_else(|| {
1032                    D::Error::custom(
1033                        "weak Arc anchor must refer to an existing strong anchor via alias",
1034                    )
1035                })?;
1036                match anchor_store::get_arc::<T>(id).map_err(D::Error::custom)? {
1037                    Some(arc) => Ok(ArcWeakAnchor(Arc::downgrade(&arc))),
1038                    None if anchor_store::arc_anchor_reentrant(id) => Err(D::Error::custom(
1039                        "Recursive references require ArcRecursion",
1040                    )),
1041                    None => Err(D::Error::custom(
1042                        "weak Arc anchor refers to unknown anchor; strong anchor must be defined before weak",
1043                    )),
1044                }
1045            }
1046        }
1047        deserializer
1048            .deserialize_newtype_struct("__yaml_arc_weak_anchor", ArcWeakVisitor(PhantomData))
1049    }
1050}
1051
1052#[cfg(feature = "deserialize")]
1053impl<'de, T> serde_core::de::Deserialize<'de> for RcRecursion<T>
1054where
1055    T: serde_core::de::Deserialize<'de> + 'static,
1056{
1057    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1058    where
1059        D: serde_core::de::Deserializer<'de>,
1060    {
1061        struct RcRecursionVisitor<T>(PhantomData<T>);
1062        impl<'de, T> Visitor<'de> for RcRecursionVisitor<T>
1063        where
1064            T: serde_core::de::Deserialize<'de> + 'static,
1065        {
1066            type Value = RcRecursion<T>;
1067            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1068                f.write_str(
1069                    "an RcRecursion referring to a previously defined recursive strong anchor (via alias)",
1070                )
1071            }
1072            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
1073            where
1074                D: serde_core::de::Deserializer<'de>,
1075            {
1076                let id = anchor_store::current_rc_recursive_anchor().ok_or_else(|| {
1077                    D::Error::custom(
1078                        "RcRecursion must refer to an existing recursive strong anchor via alias",
1079                    )
1080                })?;
1081                let _ = <serde_core::de::IgnoredAny as serde_core::de::Deserialize>::deserialize(
1082                    deserializer,
1083                )?;
1084                match anchor_store::get_rc_recursive::<RefCell<Option<T>>>(id)
1085                    .map_err(D::Error::custom)?
1086                {
1087                    Some(rc) => Ok(RcRecursion(Rc::downgrade(&rc))),
1088                    None => Err(D::Error::custom(
1089                        "RcRecursion refers to unknown recursive anchor id",
1090                    )),
1091                }
1092            }
1093        }
1094        deserializer
1095            .deserialize_newtype_struct("__yaml_rc_recursion", RcRecursionVisitor(PhantomData))
1096    }
1097}
1098
1099#[cfg(feature = "deserialize")]
1100impl<'de, T> serde_core::de::Deserialize<'de> for ArcRecursion<T>
1101where
1102    T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
1103{
1104    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1105    where
1106        D: serde_core::de::Deserializer<'de>,
1107    {
1108        struct ArcRecursionVisitor<T>(PhantomData<T>);
1109        impl<'de, T> Visitor<'de> for ArcRecursionVisitor<T>
1110        where
1111            T: serde_core::de::Deserialize<'de> + Send + Sync + 'static,
1112        {
1113            type Value = ArcRecursion<T>;
1114            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1115                f.write_str(
1116                    "an ArcRecursion referring to a previously defined recursive strong anchor (via alias)",
1117                )
1118            }
1119            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
1120            where
1121                D: serde_core::de::Deserializer<'de>,
1122            {
1123                let id = anchor_store::current_arc_recursive_anchor().ok_or_else(|| {
1124                    D::Error::custom(
1125                        "ArcRecursion must refer to an existing recursive strong anchor via alias",
1126                    )
1127                })?;
1128                let _ = <serde_core::de::IgnoredAny as serde_core::de::Deserialize>::deserialize(
1129                    deserializer,
1130                )?;
1131                match anchor_store::get_arc_recursive::<Mutex<Option<T>>>(id)
1132                    .map_err(D::Error::custom)?
1133                {
1134                    Some(arc) => Ok(ArcRecursion(Arc::downgrade(&arc))),
1135                    None => Err(D::Error::custom(
1136                        "ArcRecursion refers to unknown recursive anchor id",
1137                    )),
1138                }
1139            }
1140        }
1141        deserializer
1142            .deserialize_newtype_struct("__yaml_arc_recursion", ArcRecursionVisitor(PhantomData))
1143    }
1144}