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::de::{Error as _, Visitor};
54
55#[cfg(feature = "deserialize")]
56use crate::anchor_store;
57
58/// A wrapper around [`Rc<T>`] that opt-ins a field for **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 opt-ins a field for **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 [`Weak<T>`] (from [`std::rc`]) that opt-ins for **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` cannot be safely reconstructed into a `Weak` without a shared registry; we reject it.
117/// > Ask if you want an ID/registry-based scheme to restore sharing.
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 [`Weak<T>`] (from [`std::sync`]) that opt-ins for **anchor emission**.
139///
140/// This variant is thread-safe and uses [`Arc`] / [`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/// The possibly recursive reference to the parent anchor that must be [`ArcRecursive`], thread safe
255/// It is more complex to use than [`RcRecursive`] (you need to 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    /// Borrow the inner value
419    pub fn borrow(&self) -> std::cell::Ref<'_, T> {
420        let borrowed = self.0.as_ref().borrow();
421        std::cell::Ref::map(borrowed, |opt: &Option<T>| {
422            opt.as_ref().expect("recursive Rc anchor not initialized")
423        })
424    }
425}
426
427impl<T> ArcRecursive<T> {
428    /// Create a new recursive anchor with an initialized value.
429    pub fn wrapping(x: T) -> Self {
430        ArcRecursive(Arc::new(Mutex::new(Some(x))))
431    }
432
433    /// Lock the recursive anchor value so that it can be accessed safely.
434    pub fn lock(&self) -> std::sync::LockResult<std::sync::MutexGuard<'_, Option<T>>> {
435        self.0.lock()
436    }
437}
438
439// ===== Weak helpers =====
440
441impl<T> RcWeakAnchor<T> {
442    /// Try to upgrade the weak reference to [`Rc<T>`].
443    /// Returns [`None`] if the value has been dropped.
444    #[inline]
445    pub fn upgrade(&self) -> Option<Rc<T>> {
446        self.0.upgrade()
447    }
448
449    /// Returns `true` if the underlying value has been dropped (no strong refs remain).
450    #[inline]
451    pub fn is_dangling(&self) -> bool {
452        self.0.strong_count() == 0
453    }
454}
455impl<T> RcRecursion<T> {
456    /// Try to upgrade the weak reference to [`RcRecursive<T>`].
457    #[inline]
458    pub fn upgrade(&self) -> Option<RcRecursive<T>> {
459        self.0.upgrade().map(RcRecursive)
460    }
461
462    /// Access the recursive value in one step, if it is still alive.
463    #[inline]
464    pub fn with<R>(&self, f: impl FnOnce(&T) -> R) -> Option<R> {
465        let upgraded = self.upgrade()?;
466        let borrowed = upgraded.borrow();
467        Some(f(&borrowed))
468    }
469
470    /// Returns `true` if the underlying value has been dropped (no strong refs remain).
471    #[inline]
472    pub fn is_dangling(&self) -> bool {
473        self.0.strong_count() == 0
474    }
475}
476impl<T> ArcRecursion<T> {
477    /// Try to upgrade the weak reference to [`ArcRecursive<T>`].
478    #[inline]
479    pub fn upgrade(&self) -> Option<ArcRecursive<T>> {
480        self.0.upgrade().map(ArcRecursive)
481    }
482
483    /// Access the recursive value in one step, if it is still alive.
484    #[inline]
485    pub fn with<R>(&self, f: impl FnOnce(&T) -> R) -> Option<R> {
486        let upgraded = self.upgrade()?;
487        let guard = upgraded.lock().ok()?;
488        let value = guard.as_ref()?;
489        Some(f(value))
490    }
491
492    /// Returns `true` if the underlying value has been dropped (no strong refs remain).
493    #[inline]
494    pub fn is_dangling(&self) -> bool {
495        self.0.strong_count() == 0
496    }
497}
498impl<T> ArcWeakAnchor<T> {
499    /// Try to upgrade the weak reference to [`Arc<T>`].
500    /// Returns [`None`] if the value has been dropped.
501    #[inline]
502    pub fn upgrade(&self) -> Option<Arc<T>> {
503        self.0.upgrade()
504    }
505
506    /// Returns `true` if the underlying value has been dropped (no strong refs remain).
507    #[inline]
508    pub fn is_dangling(&self) -> bool {
509        self.0.strong_count() == 0
510    }
511}
512
513// ===== Pointer-equality PartialEq/Eq =====
514
515impl<T> PartialEq for RcAnchor<T> {
516    #[inline]
517    fn eq(&self, other: &Self) -> bool {
518        Rc::ptr_eq(&self.0, &other.0)
519    }
520}
521impl<T> Eq for RcAnchor<T> {}
522
523impl<T> PartialEq for ArcAnchor<T> {
524    #[inline]
525    fn eq(&self, other: &Self) -> bool {
526        Arc::ptr_eq(&self.0, &other.0)
527    }
528}
529impl<T> Eq for ArcAnchor<T> {}
530
531impl<T> PartialEq for RcWeakAnchor<T> {
532    #[inline]
533    fn eq(&self, other: &Self) -> bool {
534        self.0.ptr_eq(&other.0)
535    }
536}
537impl<T> Eq for RcWeakAnchor<T> {}
538
539impl<T> PartialEq for RcRecursion<T> {
540    #[inline]
541    fn eq(&self, other: &Self) -> bool {
542        self.0.ptr_eq(&other.0)
543    }
544}
545impl<T> Eq for RcRecursion<T> {}
546
547impl<T> PartialEq for ArcWeakAnchor<T> {
548    #[inline]
549    fn eq(&self, other: &Self) -> bool {
550        self.0.ptr_eq(&other.0)
551    }
552}
553impl<T> PartialEq for RcRecursive<T> {
554    #[inline]
555    fn eq(&self, other: &Self) -> bool {
556        Rc::ptr_eq(&self.0, &other.0)
557    }
558}
559impl<T> Eq for RcRecursive<T> {}
560
561impl<T> PartialEq for ArcRecursion<T> {
562    #[inline]
563    fn eq(&self, other: &Self) -> bool {
564        self.0.ptr_eq(&other.0)
565    }
566}
567impl<T> Eq for ArcRecursion<T> {}
568
569impl<T> PartialEq for ArcRecursive<T> {
570    #[inline]
571    fn eq(&self, other: &Self) -> bool {
572        Arc::ptr_eq(&self.0, &other.0)
573    }
574}
575impl<T> Eq for ArcRecursive<T> {}
576impl<T> Eq for ArcWeakAnchor<T> {}
577
578// ===== Debug =====
579
580impl<T> fmt::Debug for RcAnchor<T> {
581    #[inline]
582    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
583        write!(f, "RcAnchor({:p})", Rc::as_ptr(&self.0))
584    }
585}
586impl<T> fmt::Debug for ArcAnchor<T> {
587    #[inline]
588    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
589        write!(f, "ArcAnchor({:p})", Arc::as_ptr(&self.0))
590    }
591}
592impl<T> fmt::Debug for RcWeakAnchor<T> {
593    #[inline]
594    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
595        if let Some(rc) = self.0.upgrade() {
596            write!(f, "RcWeakAnchor(upgrade={:p})", Rc::as_ptr(&rc))
597        } else {
598            write!(f, "RcWeakAnchor(dangling)")
599        }
600    }
601}
602impl<T> fmt::Debug for ArcWeakAnchor<T> {
603    #[inline]
604    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
605        if let Some(arc) = self.0.upgrade() {
606            write!(f, "ArcWeakAnchor(upgrade={:p})", Arc::as_ptr(&arc))
607        } else {
608            write!(f, "ArcWeakAnchor(dangling)")
609        }
610    }
611}
612impl<T> fmt::Debug for RcRecursive<T> {
613    #[inline]
614    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
615        write!(f, "RcRecursive({:p})", Rc::as_ptr(&self.0))
616    }
617}
618impl<T> fmt::Debug for ArcRecursive<T> {
619    #[inline]
620    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
621        write!(f, "ArcRecursive({:p})", Arc::as_ptr(&self.0))
622    }
623}
624impl<T> fmt::Debug for RcRecursion<T> {
625    #[inline]
626    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
627        if let Some(rc) = self.0.upgrade() {
628            write!(f, "RcRecursion(upgrade={:p})", Rc::as_ptr(&rc))
629        } else {
630            write!(f, "RcRecursion(dangling)")
631        }
632    }
633}
634impl<T> fmt::Debug for ArcRecursion<T> {
635    #[inline]
636    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
637        if let Some(arc) = self.0.upgrade() {
638            write!(f, "ArcRecursion(upgrade={:p})", Arc::as_ptr(&arc))
639        } else {
640            write!(f, "ArcRecursion(dangling)")
641        }
642    }
643}
644
645// ===== Default =====
646
647impl<T: Default> Default for RcAnchor<T> {
648    #[inline]
649    fn default() -> Self {
650        RcAnchor(Rc::new(T::default()))
651    }
652}
653impl<T: Default> Default for ArcAnchor<T> {
654    fn default() -> Self {
655        ArcAnchor(Arc::new(T::default()))
656    }
657}
658impl<T: Default> Default for RcRecursive<T> {
659    #[inline]
660    fn default() -> Self {
661        RcRecursive(Rc::new(RefCell::new(Some(T::default()))))
662    }
663}
664impl<T: Default> Default for ArcRecursive<T> {
665    fn default() -> Self {
666        ArcRecursive(Arc::new(Mutex::new(Some(T::default()))))
667    }
668}
669
670// -------------------------------
671// Deserialize impls
672// -------------------------------
673#[cfg(feature = "deserialize")]
674impl<'de, T> serde::de::Deserialize<'de> for RcAnchor<T>
675where
676    T: serde::de::Deserialize<'de> + 'static,
677{
678    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
679    where
680        D: serde::de::Deserializer<'de>,
681    {
682        struct RcAnchorVisitor<T>(PhantomData<T>);
683
684        impl<'de, T> Visitor<'de> for RcAnchorVisitor<T>
685        where
686            T: serde::de::Deserialize<'de> + 'static,
687        {
688            type Value = RcAnchor<T>;
689
690            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
691                f.write_str("an RcAnchor newtype")
692            }
693
694            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
695            where
696                D: serde::de::Deserializer<'de>,
697            {
698                let anchor_id = anchor_store::claim_rc_anchor();
699                let existing = match anchor_id {
700                    Some(id) => {
701                        Some((id, anchor_store::get_rc::<T>(id).map_err(D::Error::custom)?))
702                    }
703                    None => None,
704                };
705                if let Some((id, None)) = existing
706                    && anchor_store::rc_anchor_reentrant(id)
707                {
708                    return Err(D::Error::custom(
709                        "Recursive references require weak anchors",
710                    ));
711                }
712
713                let value = T::deserialize(deserializer)?;
714                if let Some((_, Some(rc))) = existing {
715                    drop(value);
716                    return Ok(RcAnchor(rc));
717                }
718                if let Some((id, None)) = existing {
719                    let rc = Rc::new(value);
720                    anchor_store::store_rc(id, rc.clone());
721                    return Ok(RcAnchor(rc));
722                }
723                Ok(RcAnchor(Rc::new(value)))
724            }
725        }
726
727        deserializer.deserialize_newtype_struct("__yaml_rc_anchor", RcAnchorVisitor(PhantomData))
728    }
729}
730
731#[cfg(feature = "deserialize")]
732impl<'de, T> serde::de::Deserialize<'de> for ArcAnchor<T>
733where
734    T: serde::de::Deserialize<'de> + Send + Sync + 'static,
735{
736    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
737    where
738        D: serde::de::Deserializer<'de>,
739    {
740        struct ArcAnchorVisitor<T>(PhantomData<T>);
741
742        impl<'de, T> Visitor<'de> for ArcAnchorVisitor<T>
743        where
744            T: serde::de::Deserialize<'de> + Send + Sync + 'static,
745        {
746            type Value = ArcAnchor<T>;
747
748            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
749                f.write_str("an ArcAnchor newtype")
750            }
751
752            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
753            where
754                D: serde::de::Deserializer<'de>,
755            {
756                let anchor_id = anchor_store::claim_arc_anchor();
757                let existing = match anchor_id {
758                    Some(id) => Some((
759                        id,
760                        anchor_store::get_arc::<T>(id).map_err(D::Error::custom)?,
761                    )),
762                    None => None,
763                };
764                if let Some((id, None)) = existing
765                    && anchor_store::arc_anchor_reentrant(id)
766                {
767                    return Err(D::Error::custom(
768                        "Recursive references require weak anchors",
769                    ));
770                }
771
772                let value = T::deserialize(deserializer)?;
773                if let Some((_, Some(arc))) = existing {
774                    drop(value);
775                    return Ok(ArcAnchor(arc));
776                }
777                if let Some((id, None)) = existing {
778                    let arc = Arc::new(value);
779                    anchor_store::store_arc(id, arc.clone());
780                    return Ok(ArcAnchor(arc));
781                }
782                Ok(ArcAnchor(Arc::new(value)))
783            }
784        }
785
786        deserializer.deserialize_newtype_struct("__yaml_arc_anchor", ArcAnchorVisitor(PhantomData))
787    }
788}
789
790#[cfg(feature = "deserialize")]
791impl<'de, T> serde::de::Deserialize<'de> for RcRecursive<T>
792where
793    T: serde::de::Deserialize<'de> + 'static,
794{
795    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
796    where
797        D: serde::de::Deserializer<'de>,
798    {
799        struct RcRecursiveVisitor<T>(PhantomData<T>);
800
801        impl<'de, T> Visitor<'de> for RcRecursiveVisitor<T>
802        where
803            T: serde::de::Deserialize<'de> + 'static,
804        {
805            type Value = RcRecursive<T>;
806
807            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
808                f.write_str("an RcRecursive newtype")
809            }
810
811            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
812            where
813                D: serde::de::Deserializer<'de>,
814            {
815                let anchor_id = anchor_store::claim_rc_recursive_anchor();
816                let existing = match anchor_id {
817                    Some(id) => Some((
818                        id,
819                        anchor_store::get_rc_recursive::<RefCell<Option<T>>>(id)
820                            .map_err(D::Error::custom)?,
821                    )),
822                    None => None,
823                };
824                if let Some((id, None)) = existing
825                    && anchor_store::rc_recursive_reentrant(id)
826                {
827                    return Err(D::Error::custom(
828                        "recursive references require weak recursion types",
829                    ));
830                }
831
832                if let Some((_, Some(rc))) = existing {
833                    let value = T::deserialize(deserializer)?;
834                    drop(value);
835                    return Ok(RcRecursive(rc));
836                }
837
838                if let Some((id, None)) = existing {
839                    let rc = Rc::new(RefCell::new(None));
840                    anchor_store::store_rc_recursive(id, rc.clone());
841
842                    let value = T::deserialize(deserializer)?;
843                    *rc.borrow_mut() = Some(value);
844                    return Ok(RcRecursive(rc));
845                }
846
847                let value = T::deserialize(deserializer)?;
848                Ok(RcRecursive(Rc::new(RefCell::new(Some(value)))))
849            }
850        }
851
852        deserializer
853            .deserialize_newtype_struct("__yaml_rc_recursive", RcRecursiveVisitor(PhantomData))
854    }
855}
856
857#[cfg(feature = "deserialize")]
858impl<'de, T> serde::de::Deserialize<'de> for ArcRecursive<T>
859where
860    T: serde::de::Deserialize<'de> + Send + Sync + 'static,
861{
862    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
863    where
864        D: serde::de::Deserializer<'de>,
865    {
866        struct ArcRecursiveVisitor<T>(PhantomData<T>);
867
868        impl<'de, T> Visitor<'de> for ArcRecursiveVisitor<T>
869        where
870            T: serde::de::Deserialize<'de> + Send + Sync + 'static,
871        {
872            type Value = ArcRecursive<T>;
873
874            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
875                f.write_str("an ArcRecursive newtype")
876            }
877
878            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
879            where
880                D: serde::de::Deserializer<'de>,
881            {
882                let anchor_id = anchor_store::claim_arc_recursive_anchor();
883                let existing = match anchor_id {
884                    Some(id) => Some((
885                        id,
886                        anchor_store::get_arc_recursive::<Mutex<Option<T>>>(id)
887                            .map_err(D::Error::custom)?,
888                    )),
889                    None => None,
890                };
891                if let Some((id, None)) = existing
892                    && anchor_store::arc_recursive_reentrant(id)
893                {
894                    return Err(D::Error::custom(
895                        "recursive references require weak recursion types",
896                    ));
897                }
898
899                if let Some((_, Some(arc))) = existing {
900                    let value = T::deserialize(deserializer)?;
901                    drop(value);
902                    return Ok(ArcRecursive(arc));
903                }
904
905                if let Some((id, None)) = existing {
906                    let arc = Arc::new(Mutex::new(None));
907                    anchor_store::store_arc_recursive(id, arc.clone());
908
909                    let value = T::deserialize(deserializer)?;
910                    *arc.lock()
911                        .map_err(|_| D::Error::custom("recursive Arc anchor mutex poisoned"))? =
912                        Some(value);
913                    return Ok(ArcRecursive(arc));
914                }
915
916                let value = T::deserialize(deserializer)?;
917                Ok(ArcRecursive(Arc::new(Mutex::new(Some(value)))))
918            }
919        }
920
921        deserializer
922            .deserialize_newtype_struct("__yaml_arc_recursive", ArcRecursiveVisitor(PhantomData))
923    }
924}
925
926// -------------------------------
927// Deserialize impls for WEAK anchors (RcWeakAnchor / ArcWeakAnchor)
928// -------------------------------
929#[cfg(feature = "deserialize")]
930impl<'de, T> serde::de::Deserialize<'de> for RcWeakAnchor<T>
931where
932    T: serde::de::Deserialize<'de> + 'static,
933{
934    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
935    where
936        D: serde::de::Deserializer<'de>,
937    {
938        struct RcWeakVisitor<T>(PhantomData<T>);
939        impl<'de, T> Visitor<'de> for RcWeakVisitor<T>
940        where
941            T: serde::de::Deserialize<'de> + 'static,
942        {
943            type Value = RcWeakAnchor<T>;
944            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
945                f.write_str(
946                    "an RcWeakAnchor referring to a previously defined strong anchor (via alias)",
947                )
948            }
949            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
950            where
951                D: serde::de::Deserializer<'de>,
952            {
953                // `null` is the serialization form for dangling weak refs.
954                let is_null =
955                    <Option<serde::de::IgnoredAny> as serde::de::Deserialize>::deserialize(
956                        deserializer,
957                    )?
958                    .is_none();
959                if is_null {
960                    return Ok(RcWeakAnchor(RcWeak::new()));
961                }
962
963                // Anchor context is established by de.rs when the special name is used.
964                let id = anchor_store::current_rc_anchor().ok_or_else(|| {
965                    D::Error::custom(
966                        "weak Rc anchor must refer to an existing strong anchor via alias",
967                    )
968                })?;
969                // Look up the strong reference by id and downgrade.
970                match anchor_store::get_rc::<T>(id).map_err(D::Error::custom)? {
971                    Some(rc) => Ok(RcWeakAnchor(Rc::downgrade(&rc))),
972                    None if anchor_store::rc_anchor_reentrant(id) => {
973                        Err(D::Error::custom("Recursive references require RcRecursion"))
974                    }
975                    None => Err(D::Error::custom(
976                        "weak Rc anchor refers to unknown anchor; strong anchor must be defined before weak",
977                    )),
978                }
979            }
980        }
981        deserializer.deserialize_newtype_struct("__yaml_rc_weak_anchor", RcWeakVisitor(PhantomData))
982    }
983}
984
985#[cfg(feature = "deserialize")]
986impl<'de, T> serde::de::Deserialize<'de> for ArcWeakAnchor<T>
987where
988    T: serde::de::Deserialize<'de> + Send + Sync + 'static,
989{
990    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
991    where
992        D: serde::de::Deserializer<'de>,
993    {
994        struct ArcWeakVisitor<T>(PhantomData<T>);
995        impl<'de, T> Visitor<'de> for ArcWeakVisitor<T>
996        where
997            T: serde::de::Deserialize<'de> + Send + Sync + 'static,
998        {
999            type Value = ArcWeakAnchor<T>;
1000            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1001                f.write_str(
1002                    "an ArcWeakAnchor referring to a previously defined strong anchor (via alias)",
1003                )
1004            }
1005            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
1006            where
1007                D: serde::de::Deserializer<'de>,
1008            {
1009                let is_null =
1010                    <Option<serde::de::IgnoredAny> as serde::de::Deserialize>::deserialize(
1011                        deserializer,
1012                    )?
1013                    .is_none();
1014                if is_null {
1015                    return Ok(ArcWeakAnchor(ArcWeak::new()));
1016                }
1017
1018                let id = anchor_store::current_arc_anchor().ok_or_else(|| {
1019                    D::Error::custom(
1020                        "weak Arc anchor must refer to an existing strong anchor via alias",
1021                    )
1022                })?;
1023                match anchor_store::get_arc::<T>(id).map_err(D::Error::custom)? {
1024                    Some(arc) => Ok(ArcWeakAnchor(Arc::downgrade(&arc))),
1025                    None if anchor_store::arc_anchor_reentrant(id) => Err(D::Error::custom(
1026                        "Recursive references require ArcRecursion",
1027                    )),
1028                    None => Err(D::Error::custom(
1029                        "weak Arc anchor refers to unknown anchor; strong anchor must be defined before weak",
1030                    )),
1031                }
1032            }
1033        }
1034        deserializer
1035            .deserialize_newtype_struct("__yaml_arc_weak_anchor", ArcWeakVisitor(PhantomData))
1036    }
1037}
1038
1039#[cfg(feature = "deserialize")]
1040impl<'de, T> serde::de::Deserialize<'de> for RcRecursion<T>
1041where
1042    T: serde::de::Deserialize<'de> + 'static,
1043{
1044    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1045    where
1046        D: serde::de::Deserializer<'de>,
1047    {
1048        struct RcRecursionVisitor<T>(PhantomData<T>);
1049        impl<'de, T> Visitor<'de> for RcRecursionVisitor<T>
1050        where
1051            T: serde::de::Deserialize<'de> + 'static,
1052        {
1053            type Value = RcRecursion<T>;
1054            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1055                f.write_str(
1056                    "an RcRecursion referring to a previously defined recursive strong anchor (via alias)",
1057                )
1058            }
1059            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
1060            where
1061                D: serde::de::Deserializer<'de>,
1062            {
1063                let id = anchor_store::current_rc_recursive_anchor().ok_or_else(|| {
1064                    D::Error::custom(
1065                        "RcRecursion must refer to an existing recursive strong anchor via alias",
1066                    )
1067                })?;
1068                let _ =
1069                    <serde::de::IgnoredAny as serde::de::Deserialize>::deserialize(deserializer)?;
1070                match anchor_store::get_rc_recursive::<RefCell<Option<T>>>(id)
1071                    .map_err(D::Error::custom)?
1072                {
1073                    Some(rc) => Ok(RcRecursion(Rc::downgrade(&rc))),
1074                    None => Err(D::Error::custom(
1075                        "RcRecursion refers to unknown recursive anchor id",
1076                    )),
1077                }
1078            }
1079        }
1080        deserializer
1081            .deserialize_newtype_struct("__yaml_rc_recursion", RcRecursionVisitor(PhantomData))
1082    }
1083}
1084
1085#[cfg(feature = "deserialize")]
1086impl<'de, T> serde::de::Deserialize<'de> for ArcRecursion<T>
1087where
1088    T: serde::de::Deserialize<'de> + Send + Sync + 'static,
1089{
1090    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1091    where
1092        D: serde::de::Deserializer<'de>,
1093    {
1094        struct ArcRecursionVisitor<T>(PhantomData<T>);
1095        impl<'de, T> Visitor<'de> for ArcRecursionVisitor<T>
1096        where
1097            T: serde::de::Deserialize<'de> + Send + Sync + 'static,
1098        {
1099            type Value = ArcRecursion<T>;
1100            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1101                f.write_str(
1102                    "an ArcRecursion referring to a previously defined recursive strong anchor (via alias)",
1103                )
1104            }
1105            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
1106            where
1107                D: serde::de::Deserializer<'de>,
1108            {
1109                let id = anchor_store::current_arc_recursive_anchor().ok_or_else(|| {
1110                    D::Error::custom(
1111                        "ArcRecursion must refer to an existing recursive strong anchor via alias",
1112                    )
1113                })?;
1114                let _ =
1115                    <serde::de::IgnoredAny as serde::de::Deserialize>::deserialize(deserializer)?;
1116                match anchor_store::get_arc_recursive::<Mutex<Option<T>>>(id)
1117                    .map_err(D::Error::custom)?
1118                {
1119                    Some(arc) => Ok(ArcRecursion(Arc::downgrade(&arc))),
1120                    None => Err(D::Error::custom(
1121                        "ArcRecursion refers to unknown recursive anchor id",
1122                    )),
1123                }
1124            }
1125        }
1126        deserializer
1127            .deserialize_newtype_struct("__yaml_arc_recursion", ArcRecursionVisitor(PhantomData))
1128    }
1129}