x_bow/impls/stdlib/
rc.rs

1use std::{
2    cell::{Ref, RefMut},
3    fmt::Debug,
4    hash::Hasher,
5    ops::Deref,
6    rc::Rc,
7};
8
9use crate::{path::Path, trackable::Trackable};
10
11impl<T: Trackable> Trackable for Rc<T> {
12    type PathBuilder<P: Path<Out = Self>> = RcPathBuilder<T, P>;
13
14    fn new_path_builder<P: Path<Out = Self>>(parent: P) -> Self::PathBuilder<P> {
15        RcPathBuilder { inner_path: parent }
16    }
17}
18
19#[derive(x_bow_macros::IntoPath)]
20#[into_path(prefix = crate::trackable)]
21pub struct RcPathBuilder<T, P: Path<Out = Rc<T>>> {
22    inner_path: P,
23}
24
25impl<T, P: Path<Out = Rc<T>>> Deref for RcPathBuilder<T, P> {
26    type Target = P;
27
28    fn deref(&self) -> &Self::Target {
29        &self.inner_path
30    }
31}
32
33impl<T: Trackable, P: Path<Out = Rc<T>>> RcPathBuilder<T, P> {
34    pub fn content(self) -> T::PathBuilder<RcMapper<T, P>> {
35        T::new_path_builder(RcMapper {
36            parent: self.inner_path,
37        })
38    }
39}
40
41pub struct RcMapper<T: ?Sized, P: Path<Out = Rc<T>>> {
42    parent: P,
43}
44
45impl<T: ?Sized, P: Path<Out = Rc<T>> + Clone> Clone for RcMapper<T, P> {
46    fn clone(&self) -> Self {
47        Self {
48            parent: self.parent.clone(),
49        }
50    }
51}
52impl<T: ?Sized, P: Path<Out = Rc<T>> + Copy> Copy for RcMapper<T, P> {}
53
54impl<T: ?Sized, P: Path<Out = Rc<T>> + Debug> Debug for RcMapper<T, P> {
55    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56        self.parent.fmt(f)?;
57        f.write_str("→(Rc content)")
58    }
59}
60impl<T: ?Sized, P: Path<Out = Rc<T>>> Path for RcMapper<T, P> {
61    type Out = T;
62
63    fn path_borrow(&self) -> Option<std::cell::Ref<'_, Self::Out>> {
64        self.parent.path_borrow().map(|r| Ref::map(r, |rc| &**rc))
65    }
66    fn path_borrow_mut(&self) -> Option<std::cell::RefMut<'_, Self::Out>> {
67        self.parent
68            .path_borrow_mut()
69            .and_then(|r| RefMut::filter_map(r, |rc| Rc::get_mut(rc)).ok())
70    }
71
72    fn visit_hashes(&self, visitor: &mut crate::hash_visitor::HashVisitor) {
73        self.parent.visit_hashes(visitor);
74        visitor.write_u8(0);
75        visitor.finish_one();
76    }
77    fn store_wakers(&self) -> &std::cell::RefCell<crate::wakers::StoreWakers> {
78        self.parent.store_wakers()
79    }
80}