easy_node/
nr.rs

1//! Provider of [`Nr`].
2
3use crate::util::cmp_ptr;
4use crate::Nw;
5use std::cmp::Ordering;
6use std::fmt::{Display, Formatter, Result};
7use std::hash::{Hash, Hasher};
8use std::mem;
9use std::ops::Deref;
10use std::rc::{Rc, Weak};
11
12/// Strong reference to node.
13#[repr(transparent)]
14#[derive(Debug, Default)]
15pub struct Nr<T: ?Sized>(Rc<T>);
16
17impl<T> Nr<T> {
18    /// Create new instance.
19    pub fn new(value: T) -> Self {
20        Self(Rc::new(value))
21    }
22
23    /// Create self-referencing instance.
24    pub fn new_cyclic<F>(data_fn: F) -> Self
25    where
26        F: FnOnce(&Nw<T>) -> T,
27    {
28        let conv_arg = |w: &_| Nw::from_base(Weak::clone(w));
29        let base = Rc::new_cyclic(|w| data_fn(&conv_arg(w)));
30        Self(base)
31    }
32}
33
34impl<T: ?Sized> Nr<T> {
35    /// Create reference from base object.
36    #[must_use]
37    #[inline(always)]
38    pub fn as_base(base: &Rc<T>) -> &Self {
39        unsafe { mem::transmute(base) }
40    }
41
42    /// Create instance from base object.
43    #[must_use]
44    #[inline(always)]
45    pub fn from_base(base: Rc<T>) -> Self {
46        Self(base)
47    }
48
49    /// Get base object.
50    #[must_use]
51    #[inline(always)]
52    pub fn base(this: &Self) -> &Rc<T> {
53        &this.0
54    }
55
56    /// Create weak pointer to this node.
57    #[must_use]
58    pub fn downgrade(this: &Self) -> Nw<T> {
59        Nw::from_base(Rc::downgrade(&this.0))
60    }
61
62    /// Get the number of strong pointer to this node.
63    #[inline(always)]
64    pub fn strong_count(this: &Self) -> usize {
65        Rc::strong_count(&this.0)
66    }
67
68    /// Get the number of weak pointer to this node.
69    #[inline(always)]
70    pub fn weak_count(this: &Self) -> usize {
71        Rc::weak_count(&this.0)
72    }
73}
74
75impl<T: ?Sized> Clone for Nr<T> {
76    fn clone(&self) -> Self {
77        Self(Rc::clone(&self.0))
78    }
79}
80
81impl<T: ?Sized> Deref for Nr<T> {
82    type Target = T;
83
84    fn deref(&self) -> &Self::Target {
85        self.0.deref()
86    }
87}
88
89impl<T: ?Sized + Display> Display for Nr<T> {
90    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
91        self.0.fmt(f)
92    }
93}
94
95impl<T: ?Sized> Eq for Nr<T> {}
96
97impl<T: ?Sized> Hash for Nr<T> {
98    fn hash<H: Hasher>(&self, state: &mut H) {
99        Rc::as_ptr(&self.0).hash(state);
100    }
101}
102
103impl<T: ?Sized> Ord for Nr<T> {
104    fn cmp(&self, other: &Self) -> Ordering {
105        cmp_ptr(Rc::as_ptr(&self.0), Rc::as_ptr(&other.0))
106    }
107}
108
109impl<T: ?Sized> PartialEq for Nr<T> {
110    fn eq(&self, other: &Self) -> bool {
111        Rc::ptr_eq(&self.0, &other.0)
112    }
113}
114
115impl<T: ?Sized> PartialOrd for Nr<T> {
116    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
117        Some(self.cmp(other))
118    }
119}