x_bow/impls/stdlib/
vec.rs

1use std::{
2    cell::{Ref, RefMut},
3    fmt::Debug,
4    hash::Hasher,
5    ops::Deref,
6};
7
8use crate::{impls::leaf::LeafPathBuilder, path::Path, trackable::Trackable};
9
10#[derive(x_bow_macros::IntoPath)]
11#[into_path(prefix = crate::trackable)]
12pub struct VecPathBuilder<T, P: Path<Out = Vec<T>>> {
13    inner_path: P,
14}
15
16impl<T, P: Path<Out = Vec<T>>> Deref for VecPathBuilder<T, P> {
17    type Target = P;
18    fn deref(&self) -> &Self::Target {
19        &self.inner_path
20    }
21}
22
23impl<T> Trackable for Vec<T> {
24    type PathBuilder<P: Path<Out = Self>> = VecPathBuilder<T, P>;
25
26    fn new_path_builder<P: Path<Out = Self>>(parent: P) -> Self::PathBuilder<P> {
27        VecPathBuilder { inner_path: parent }
28    }
29}
30
31impl<T, P: Path<Out = Vec<T>> + Clone> Clone for VecPathBuilder<T, P> {
32    fn clone(&self) -> Self {
33        Self {
34            inner_path: self.inner_path.clone(),
35        }
36    }
37}
38impl<T, P: Path<Out = Vec<T>> + Copy> Copy for VecPathBuilder<T, P> {}
39
40impl<T: Trackable, P: Path<Out = Vec<T>>> VecPathBuilder<T, P> {
41    pub fn index(self, index: usize) -> T::PathBuilder<VecIndexMapper<T, P>> {
42        T::new_path_builder(VecIndexMapper {
43            parent: self.inner_path,
44            index,
45        })
46    }
47}
48
49impl<T, P: Path<Out = Vec<T>>> VecPathBuilder<T, P> {
50    pub fn index_shallow(self, index: usize) -> LeafPathBuilder<VecIndexMapper<T, P>> {
51        LeafPathBuilder::new(VecIndexMapper {
52            parent: self.inner_path,
53            index,
54        })
55    }
56}
57
58pub struct VecIndexMapper<T, P: Path<Out = Vec<T>>> {
59    parent: P,
60    index: usize,
61}
62
63impl<T, P: Path<Out = Vec<T>> + Clone> Clone for VecIndexMapper<T, P> {
64    fn clone(&self) -> Self {
65        Self {
66            parent: self.parent.clone(),
67            index: self.index,
68        }
69    }
70}
71
72impl<T, P: Path<Out = Vec<T>> + Copy> Copy for VecIndexMapper<T, P> {}
73
74impl<T, P: Path<Out = Vec<T>> + Debug> Debug for VecIndexMapper<T, P> {
75    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76        self.parent.fmt(f)?;
77        f.write_fmt(format_args!("→(index {})", self.index))
78    }
79}
80
81impl<T, P: Path<Out = Vec<T>>> Path for VecIndexMapper<T, P> {
82    type Out = T;
83
84    fn path_borrow(&self) -> Option<std::cell::Ref<'_, Self::Out>> {
85        self.parent
86            .path_borrow()
87            .and_then(|r| Ref::filter_map(r, |s| s.get(self.index)).ok())
88    }
89    fn path_borrow_mut(&self) -> Option<std::cell::RefMut<'_, Self::Out>> {
90        self.parent
91            .path_borrow_mut()
92            .and_then(|r| RefMut::filter_map(r, |s| s.get_mut(self.index)).ok())
93    }
94
95    fn visit_hashes(&self, visitor: &mut crate::hash_visitor::HashVisitor) {
96        self.parent.visit_hashes(visitor);
97        visitor.write_usize(self.index);
98        visitor.finish_one();
99    }
100    fn store_wakers(&self) -> &std::cell::RefCell<crate::wakers::StoreWakers> {
101        self.parent.store_wakers()
102    }
103}