Skip to main content

spire_core/identity/
weak.rs

1use std::fmt;
2use std::sync::{Arc, Weak};
3
4use super::{Identity, Inner};
5
6/// A weak reference to an [`Identity`], from [`Identity::downgrade`].
7#[derive(Clone)]
8pub struct WeakIdentity(pub(super) Weak<Inner>);
9
10impl WeakIdentity {
11    /// Returns the identity, unless it is gone.
12    #[must_use]
13    pub fn upgrade(&self) -> Option<Identity> {
14        self.0.upgrade().map(Identity)
15    }
16
17    /// Whether the identity is still in use.
18    #[must_use]
19    pub fn is_alive(&self) -> bool {
20        self.0.strong_count() > 0
21    }
22
23    /// Whether this refers to `identity` itself, not merely one with the
24    /// same name.
25    #[must_use]
26    pub fn refers_to(&self, identity: &Identity) -> bool {
27        std::ptr::eq(self.0.as_ptr(), Arc::as_ptr(&identity.0))
28    }
29}
30
31impl fmt::Debug for WeakIdentity {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        f.debug_tuple("WeakIdentity")
34            .field(&self.upgrade().as_ref().map(Identity::name))
35            .finish()
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    #[test]
44    fn weak_references_outlive_their_identity() {
45        let identity = Identity::new("a");
46        let weak = identity.downgrade();
47        assert!(weak.is_alive() && weak.refers_to(&identity));
48        assert!(!weak.refers_to(&Identity::new("a")));
49        drop(identity);
50        assert!(!weak.is_alive());
51        assert!(weak.upgrade().is_none());
52    }
53}