1use crate::{Ephemeron, Finalize, Gc, Trace};
2use std::hash::{Hash, Hasher};
3
4#[derive(Debug, Trace, Finalize)]
9#[repr(transparent)]
10pub struct WeakGc<T: Trace + ?Sized + 'static> {
11 inner: Ephemeron<T, ()>,
12}
13
14impl<T: Trace + ?Sized> WeakGc<T> {
15 #[inline]
17 #[must_use]
18 pub fn new(value: &Gc<T>) -> Self {
19 Self {
20 inner: Ephemeron::new(value, ()),
21 }
22 }
23
24 #[inline]
27 #[must_use]
28 pub fn upgrade(&self) -> Option<Gc<T>> {
29 self.inner.key()
30 }
31
32 #[inline]
34 #[must_use]
35 pub fn is_upgradable(&self) -> bool {
36 self.inner.has_value()
37 }
38
39 #[must_use]
40 pub(crate) const fn inner(&self) -> &Ephemeron<T, ()> {
41 &self.inner
42 }
43}
44
45impl<T: Trace> Clone for WeakGc<T> {
46 fn clone(&self) -> Self {
47 Self {
48 inner: self.inner.clone(),
49 }
50 }
51}
52
53impl<T: Trace> From<Ephemeron<T, ()>> for WeakGc<T> {
54 fn from(inner: Ephemeron<T, ()>) -> Self {
55 Self { inner }
56 }
57}
58
59impl<T: Trace> PartialEq for WeakGc<T> {
60 fn eq(&self, other: &Self) -> bool {
61 match (self.upgrade(), other.upgrade()) {
62 (Some(a), Some(b)) => std::ptr::eq(a.as_ref(), b.as_ref()),
63 _ => false,
64 }
65 }
66}
67
68impl<T: Trace> Eq for WeakGc<T> {}
69
70impl<T: Trace> Hash for WeakGc<T> {
71 fn hash<H: Hasher>(&self, state: &mut H) {
72 if let Some(obj) = self.upgrade() {
73 std::ptr::hash(obj.as_ref(), state);
74 } else {
75 std::ptr::hash(self, state);
76 }
77 }
78}