1use std::borrow::Borrow;
2use std::fmt;
3use std::marker::PhantomData;
4use std::ops::Deref;
5use std::rc::{Rc, Weak as RcWeak};
6use std::sync::{Arc, Weak as ArcWeak};
7
8use serde::de::{Error as _, Visitor};
9
10use crate::anchor_store;
11
12#[repr(transparent)]
35#[derive(Clone)]
36pub struct RcAnchor<T: ?Sized>(pub Rc<T>);
37
38#[repr(transparent)]
60#[derive(Clone)]
61pub struct ArcAnchor<T: ?Sized>(pub Arc<T>);
62
63#[repr(transparent)]
89#[derive(Clone)]
90pub struct RcWeakAnchor<T: ?Sized>(pub RcWeak<T>);
91
92#[repr(transparent)]
115#[derive(Clone)]
116pub struct ArcWeakAnchor<T: ?Sized>(pub ArcWeak<T>);
117
118impl<T: ?Sized> From<Rc<T>> for RcAnchor<T> {
121 #[inline]
122 fn from(rc: Rc<T>) -> Self { RcAnchor(rc) }
123}
124impl<T: ?Sized> From<Arc<T>> for ArcAnchor<T> {
125 #[inline]
126 fn from(arc: Arc<T>) -> Self { ArcAnchor(arc) }
127}
128
129impl<T: ?Sized> From<&Rc<T>> for RcWeakAnchor<T> {
132 #[inline]
133 fn from(rc: &Rc<T>) -> Self { RcWeakAnchor(Rc::downgrade(rc)) }
134}
135impl<T: ?Sized> From<Rc<T>> for RcWeakAnchor<T> {
136 #[inline]
137 fn from(rc: Rc<T>) -> Self { RcWeakAnchor(Rc::downgrade(&rc)) }
138}
139impl<T: ?Sized> From<&RcAnchor<T>> for RcWeakAnchor<T> {
140 #[inline]
141 fn from(rca: &RcAnchor<T>) -> Self { RcWeakAnchor(Rc::downgrade(&rca.0)) }
142}
143impl<T: ?Sized> From<&Arc<T>> for ArcWeakAnchor<T> {
144 #[inline]
145 fn from(arc: &Arc<T>) -> Self { ArcWeakAnchor(Arc::downgrade(arc)) }
146}
147impl<T: ?Sized> From<Arc<T>> for ArcWeakAnchor<T> {
148 #[inline]
149 fn from(arc: Arc<T>) -> Self { ArcWeakAnchor(Arc::downgrade(&arc)) }
150}
151impl<T: ?Sized> From<&ArcAnchor<T>> for ArcWeakAnchor<T> {
152 #[inline]
153 fn from(ara: &ArcAnchor<T>) -> Self { ArcWeakAnchor(Arc::downgrade(&ara.0)) }
154}
155
156impl<T: ?Sized> Deref for RcAnchor<T> {
159 type Target = Rc<T>;
160 #[inline]
161 fn deref(&self) -> &Self::Target { &self.0 }
162}
163impl<T: ?Sized> Deref for ArcAnchor<T> {
164 type Target = Arc<T>;
165 #[inline]
166 fn deref(&self) -> &Self::Target { &self.0 }
167}
168impl<T: ?Sized> AsRef<Rc<T>> for RcAnchor<T> {
169 #[inline]
170 fn as_ref(&self) -> &Rc<T> { &self.0 }
171}
172impl<T: ?Sized> AsRef<Arc<T>> for ArcAnchor<T> {
173 #[inline]
174 fn as_ref(&self) -> &Arc<T> { &self.0 }
175}
176impl<T: ?Sized> Borrow<Rc<T>> for RcAnchor<T> {
177 #[inline]
178 fn borrow(&self) -> &Rc<T> { &self.0 }
179}
180impl<T: ?Sized> Borrow<Arc<T>> for ArcAnchor<T> {
181 #[inline]
182 fn borrow(&self) -> &Arc<T> { &self.0 }
183}
184impl<T: ?Sized> From<RcAnchor<T>> for Rc<T> {
185 #[inline]
186 fn from(a: RcAnchor<T>) -> Rc<T> { a.0 }
187}
188impl<T: ?Sized> From<ArcAnchor<T>> for Arc<T> {
189 #[inline]
190 fn from(a: ArcAnchor<T>) -> Arc<T> { a.0 }
191}
192
193impl<T: ?Sized> RcWeakAnchor<T> {
196 #[inline]
199 pub fn upgrade(&self) -> Option<Rc<T>> { self.0.upgrade() }
200
201 #[inline]
203 pub fn is_dangling(&self) -> bool { self.0.strong_count() == 0 }
204}
205impl<T: ?Sized> ArcWeakAnchor<T> {
206 #[inline]
209 pub fn upgrade(&self) -> Option<Arc<T>> { self.0.upgrade() }
210
211 #[inline]
213 pub fn is_dangling(&self) -> bool { self.0.strong_count() == 0 }
214}
215
216impl<T: ?Sized> PartialEq for RcAnchor<T> {
219 #[inline]
220 fn eq(&self, other: &Self) -> bool { Rc::ptr_eq(&self.0, &other.0) }
221}
222impl<T: ?Sized> Eq for RcAnchor<T> {}
223
224impl<T: ?Sized> PartialEq for ArcAnchor<T> {
225 #[inline]
226 fn eq(&self, other: &Self) -> bool { Arc::ptr_eq(&self.0, &other.0) }
227}
228impl<T: ?Sized> Eq for ArcAnchor<T> {}
229
230impl<T: ?Sized> PartialEq for RcWeakAnchor<T> {
231 #[inline]
232 fn eq(&self, other: &Self) -> bool {
233 match (self.0.upgrade(), other.0.upgrade()) {
234 (Some(a), Some(b)) => Rc::ptr_eq(&a, &b),
235 (None, None) => true,
236 _ => false,
237 }
238 }
239}
240impl<T: ?Sized> Eq for RcWeakAnchor<T> {}
241
242impl<T: ?Sized> PartialEq for ArcWeakAnchor<T> {
243 #[inline]
244 fn eq(&self, other: &Self) -> bool {
245 match (self.0.upgrade(), other.0.upgrade()) {
246 (Some(a), Some(b)) => Arc::ptr_eq(&a, &b),
247 (None, None) => true,
248 _ => false,
249 }
250 }
251}
252impl<T: ?Sized> Eq for ArcWeakAnchor<T> {}
253
254impl<T: ?Sized> fmt::Debug for RcAnchor<T> {
257 #[inline]
258 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
259 write!(f, "RcAnchor({:p})", Rc::as_ptr(&self.0))
260 }
261}
262impl<T: ?Sized> fmt::Debug for ArcAnchor<T> {
263 #[inline]
264 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
265 write!(f, "ArcAnchor({:p})", Arc::as_ptr(&self.0))
266 }
267}
268impl<T: ?Sized> fmt::Debug for RcWeakAnchor<T> {
269 #[inline]
270 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
271 if let Some(rc) = self.0.upgrade() {
272 write!(f, "RcWeakAnchor(upgrade={:p})", Rc::as_ptr(&rc))
273 } else {
274 write!(f, "RcWeakAnchor(dangling)")
275 }
276 }
277}
278impl<T: ?Sized> fmt::Debug for ArcWeakAnchor<T> {
279 #[inline]
280 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
281 if let Some(arc) = self.0.upgrade() {
282 write!(f, "ArcWeakAnchor(upgrade={:p})", Arc::as_ptr(&arc))
283 } else {
284 write!(f, "ArcWeakAnchor(dangling)")
285 }
286 }
287}
288
289impl<T: Default> Default for RcAnchor<T> {
292 #[inline]
293 fn default() -> Self { RcAnchor(Rc::new(T::default())) }
294}
295impl<T: Default> Default for ArcAnchor<T> {
296 fn default() -> Self { ArcAnchor(Arc::new(T::default())) }
297}
298
299impl<'de, T> serde::de::Deserialize<'de> for RcAnchor<T>
303where
304 T: serde::de::Deserialize<'de> + 'static,
305{
306 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
307 where
308 D: serde::de::Deserializer<'de>,
309 {
310 struct RcAnchorVisitor<T>(PhantomData<T>);
311
312 impl<'de, T> Visitor<'de> for RcAnchorVisitor<T>
313 where
314 T: serde::de::Deserialize<'de> + 'static,
315 {
316 type Value = RcAnchor<T>;
317
318 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
319 f.write_str("an RcAnchor newtype")
320 }
321
322 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
323 where
324 D: serde::de::Deserializer<'de>,
325 {
326 let anchor_id = anchor_store::current_rc_anchor();
327 let existing = match anchor_id {
328 Some(id) => Some((id, anchor_store::get_rc::<T>(id).map_err(D::Error::custom)?)),
329 None => None,
330 };
331
332 let value = T::deserialize(deserializer)?;
333 if let Some((_, Some(rc))) = existing {
334 drop(value);
335 return Ok(RcAnchor(rc));
336 }
337 if let Some((id, None)) = existing {
338 let rc = Rc::new(value);
339 anchor_store::store_rc(id, rc.clone());
340 return Ok(RcAnchor(rc));
341 }
342 Ok(RcAnchor(Rc::new(value)))
343 }
344 }
345
346 deserializer.deserialize_newtype_struct("__yaml_rc_anchor", RcAnchorVisitor(PhantomData))
347 }
348}
349
350impl<'de, T> serde::de::Deserialize<'de> for ArcAnchor<T>
351where
352 T: serde::de::Deserialize<'de> + Send + Sync + 'static,
353{
354 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
355 where
356 D: serde::de::Deserializer<'de>,
357 {
358 struct ArcAnchorVisitor<T>(PhantomData<T>);
359
360 impl<'de, T> Visitor<'de> for ArcAnchorVisitor<T>
361 where
362 T: serde::de::Deserialize<'de> + Send + Sync + 'static,
363 {
364 type Value = ArcAnchor<T>;
365
366 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
367 f.write_str("an ArcAnchor newtype")
368 }
369
370 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
371 where
372 D: serde::de::Deserializer<'de>,
373 {
374 let anchor_id = anchor_store::current_arc_anchor();
375 let existing = match anchor_id {
376 Some(id) => Some((id, anchor_store::get_arc::<T>(id).map_err(D::Error::custom)?)),
377 None => None,
378 };
379
380 let value = T::deserialize(deserializer)?;
381 if let Some((_, Some(arc))) = existing {
382 drop(value);
383 return Ok(ArcAnchor(arc));
384 }
385 if let Some((id, None)) = existing {
386 let arc = Arc::new(value);
387 anchor_store::store_arc(id, arc.clone());
388 return Ok(ArcAnchor(arc));
389 }
390 Ok(ArcAnchor(Arc::new(value)))
391 }
392 }
393
394 deserializer.deserialize_newtype_struct("__yaml_arc_anchor", ArcAnchorVisitor(PhantomData))
395 }
396}
397
398impl<'de, T> serde::de::Deserialize<'de> for RcWeakAnchor<T>
402where
403 T: serde::de::Deserialize<'de> + 'static,
404{
405 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
406 where
407 D: serde::de::Deserializer<'de>,
408 {
409 struct RcWeakVisitor<T>(PhantomData<T>);
410 impl<'de, T> Visitor<'de> for RcWeakVisitor<T>
411 where
412 T: serde::de::Deserialize<'de> + 'static,
413 {
414 type Value = RcWeakAnchor<T>;
415 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
416 f.write_str("an RcWeakAnchor referring to a previously defined strong anchor (via alias)")
417 }
418 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
419 where
420 D: serde::de::Deserializer<'de>,
421 {
422 let id = anchor_store::current_rc_anchor().ok_or_else(|| D::Error::custom("weak Rc anchor must refer to an existing strong anchor via alias"))?;
424 let _ = <serde::de::IgnoredAny as serde::de::Deserialize>::deserialize(deserializer)?;
426 match anchor_store::get_rc::<T>(id).map_err(D::Error::custom)? {
428 Some(rc) => Ok(RcWeakAnchor(Rc::downgrade(&rc))),
429 None => Err(D::Error::custom("weak Rc anchor refers to unknown anchor id; strong anchor must be defined before weak")),
430 }
431 }
432 }
433 deserializer.deserialize_newtype_struct("__yaml_rc_weak_anchor", RcWeakVisitor(PhantomData))
434 }
435}
436
437impl<'de, T> serde::de::Deserialize<'de> for ArcWeakAnchor<T>
438where
439 T: serde::de::Deserialize<'de> + Send + Sync + 'static,
440{
441 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
442 where
443 D: serde::de::Deserializer<'de>,
444 {
445 struct ArcWeakVisitor<T>(PhantomData<T>);
446 impl<'de, T> Visitor<'de> for ArcWeakVisitor<T>
447 where
448 T: serde::de::Deserialize<'de> + Send + Sync + 'static,
449 {
450 type Value = ArcWeakAnchor<T>;
451 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
452 f.write_str("an ArcWeakAnchor referring to a previously defined strong anchor (via alias)")
453 }
454 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
455 where
456 D: serde::de::Deserializer<'de>,
457 {
458 let id = anchor_store::current_arc_anchor().ok_or_else(|| D::Error::custom("weak Arc anchor must refer to an existing strong anchor via alias"))?;
459 let _ = <serde::de::IgnoredAny as serde::de::Deserialize>::deserialize(deserializer)?;
461 match anchor_store::get_arc::<T>(id).map_err(D::Error::custom)? {
462 Some(arc) => Ok(ArcWeakAnchor(Arc::downgrade(&arc))),
463 None => Err(D::Error::custom("weak Arc anchor refers to unknown anchor id; strong anchor must be defined before weak")),
464 }
465 }
466 }
467 deserializer.deserialize_newtype_struct("__yaml_arc_weak_anchor", ArcWeakVisitor(PhantomData))
468 }
469}
470