1use std::ops::{Deref, DerefMut};
17use std::sync::atomic::{AtomicUsize, Ordering};
18use std::sync::{Arc, Mutex, RwLock};
19
20use crate::{BorrowDeref, BorrowDerefMut, InnerEq};
21
22static NONCE: AtomicUsize = AtomicUsize::new(0);
24fn next_nonce() -> usize {
26 NONCE.fetch_add(1, Ordering::Relaxed)
27}
28
29#[derive(Debug)]
34pub struct Marc<T> {
35 inner: Arc<T>,
36 nonce: AtomicUsize,
37}
38impl<T: Default> Default for Marc<T> {
39 fn default() -> Self {
40 Self::from(T::default())
41 }
42}
43
44impl<T> From<T> for Marc<T> {
45 fn from(value: T) -> Self {
46 Self {
47 inner: Arc::new(value),
48 nonce: next_nonce().into(),
49 }
50 }
51}
52
53impl<T> Clone for Marc<T> {
54 fn clone(&self) -> Self {
55 Self {
56 inner: self.inner.clone(),
57 nonce: AtomicUsize::new(self.nonce.load(Ordering::Relaxed)),
58 }
59 }
60}
61
62impl<T> PartialEq for Marc<T> {
63 fn eq(&self, other: &Self) -> bool {
64 Arc::ptr_eq(&self.inner, &other.inner)
65 && self.nonce.load(Ordering::Relaxed) == other.nonce.load(Ordering::Relaxed)
66 }
67}
68
69impl<T> Marc<T> {
71 pub fn new_rw(value: T) -> Marc<RwLock<T>> {
73 Marc::<RwLock<T>>::from(RwLock::new(value))
74 }
75
76 pub fn new_mutex(value: T) -> Marc<Mutex<T>> {
78 Marc::<Mutex<T>>::from(Mutex::new(value))
79 }
80}
81
82impl<T> Marc<RwLock<T>> {
84 pub fn new(value: T) -> Self {
86 Self::from(RwLock::new(value))
87 }
88}
89impl<T> BorrowDerefMut<T> for Marc<RwLock<T>> {
90 fn borrow_mut(&self) -> impl DerefMut<Target = T> + '_ {
91 self.nonce
92 .store(NONCE.fetch_add(1, Ordering::Relaxed), Ordering::Relaxed);
93 self.inner.write().expect("poison free RwLock")
94 }
95}
96impl<T> BorrowDeref<T> for Marc<RwLock<T>> {
97 fn borrow(&self) -> impl Deref<Target = T> + '_ {
98 self.inner.read().expect("poison free RwLock")
99 }
100}
101impl<T: PartialOrd> PartialOrd for Marc<RwLock<T>> {
102 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
103 self.borrow().deref().partial_cmp(other.borrow().deref())
104 }
105}
106impl<T: PartialEq> InnerEq<T> for Marc<RwLock<T>> {
107 fn inner_eq(&self, other: &Self) -> bool {
108 self.borrow().deref() == other.borrow().deref()
109 }
110}
111#[cfg(feature = "serde")]
112impl<T: serde::Serialize> serde::Serialize for Marc<RwLock<T>> {
113 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
114 where
115 S: serde::Serializer,
116 {
117 T::serialize(self.borrow().deref(), serializer)
118 }
119}
120#[cfg(feature = "serde")]
121impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for Marc<RwLock<T>> {
122 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
123 where
124 D: serde::Deserializer<'de>,
125 {
126 T::deserialize(deserializer).map(Self::new)
127 }
128}
129
130impl<T> Marc<Mutex<T>> {
132 pub fn new(value: T) -> Self {
134 Self::from(Mutex::new(value))
135 }
136}
137impl<T> BorrowDerefMut<T> for Marc<Mutex<T>> {
138 fn borrow_mut(&self) -> impl DerefMut<Target = T> + '_ {
139 self.nonce.store(next_nonce(), Ordering::Relaxed);
140 self.inner.lock().expect("poison free Mutex")
141 }
142}
143impl<T> BorrowDeref<T> for Marc<Mutex<T>> {
144 fn borrow(&self) -> impl Deref<Target = T> + '_ {
145 self.inner.lock().expect("poison free Mutex")
146 }
147}
148impl<T: PartialOrd> PartialOrd for Marc<Mutex<T>> {
149 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
150 self.borrow().deref().partial_cmp(other.borrow().deref())
151 }
152}
153#[cfg(feature = "serde")]
154impl<T: serde::Serialize> serde::Serialize for Marc<Mutex<T>> {
155 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
156 where
157 S: serde::Serializer,
158 {
159 T::serialize(self.borrow().deref(), serializer)
160 }
161}
162#[cfg(feature = "serde")]
163impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for Marc<Mutex<T>> {
164 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
165 where
166 D: serde::Deserializer<'de>,
167 {
168 T::deserialize(deserializer).map(Self::new)
169 }
170}