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