scsys_core/cont/
container.rs

1/*
2    appellation: container <module>
3    authors: @FL03
4*/
5use super::RawContainer;
6
7/// the [`ContainerBase`] type materializes the [`RawContainer`] trait, providing a physical
8/// implementation of a generic container type
9#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
10#[cfg_attr(
11    feature = "serde",
12    derive(serde::Serialize, serde::Deserialize),
13    serde(rename_all = "snake_case")
14)]
15pub struct ContainerBase<S>
16where
17    S: RawContainer,
18{
19    /// the underlying store for the container
20    pub(crate) repr: S,
21    #[cfg_attr(feature = "serde", serde(skip))]
22    pub(crate) _marker: core::marker::PhantomData<S::Item>,
23}
24
25impl<A, S> ContainerBase<S>
26where
27    S: RawContainer<Item = A>,
28{
29    /// returns a new instance using the given store
30    pub const fn from_store(store: S) -> Self {
31        Self {
32            repr: store,
33            _marker: core::marker::PhantomData::<A>,
34        }
35    }
36    /// returns a reference to the underlying store
37    pub const fn store(&self) -> &S {
38        &self.repr
39    }
40    /// returns a mutable reference to the underlying store
41    pub const fn store_mut(&mut self) -> &mut S {
42        &mut self.repr
43    }
44    /// [`replace`](core::mem::replace) the store with another and return the previous value
45    pub const fn replace_store(&mut self, store: S) -> S {
46        core::mem::replace(self.store_mut(), store)
47    }
48    /// set the current store and return a mutable reference to the container
49    pub fn set_store(&mut self, store: S) -> &mut Self {
50        self.repr = store;
51        self
52    }
53    /// [`swap`](core::mem::swap) the store another and return a mutable reference to the
54    /// container
55    pub const fn swap_store(&mut self, store: &mut S) -> &mut Self {
56        core::mem::swap(self.store_mut(), store);
57        self
58    }
59    /// [`take`](core::mem::take) the store and return it, leaving the logical default in its
60    /// place
61    pub fn take_store(&mut self) -> S
62    where
63        S: Default,
64    {
65        core::mem::take(self.store_mut())
66    }
67    /// consumes the current instance to create another with the given store
68    pub fn with_store<T: RawContainer<Item = A>>(self, repr: T) -> ContainerBase<T> {
69        ContainerBase {
70            repr,
71            _marker: core::marker::PhantomData::<A>,
72        }
73    }
74}
75
76impl<S> AsRef<S> for ContainerBase<S>
77where
78    S: RawContainer,
79{
80    fn as_ref(&self) -> &S {
81        self.store()
82    }
83}
84
85impl<S> AsMut<S> for ContainerBase<S>
86where
87    S: RawContainer,
88{
89    fn as_mut(&mut self) -> &mut S {
90        self.store_mut()
91    }
92}
93
94impl<S> core::borrow::Borrow<S> for ContainerBase<S>
95where
96    S: RawContainer,
97{
98    fn borrow(&self) -> &S {
99        self.store()
100    }
101}
102
103impl<S> core::borrow::BorrowMut<S> for ContainerBase<S>
104where
105    S: RawContainer,
106{
107    fn borrow_mut(&mut self) -> &mut S {
108        self.store_mut()
109    }
110}
111
112impl<S> core::ops::Deref for ContainerBase<S>
113where
114    S: RawContainer,
115{
116    type Target = S;
117
118    fn deref(&self) -> &Self::Target {
119        self.store()
120    }
121}
122
123impl<S> core::ops::DerefMut for ContainerBase<S>
124where
125    S: RawContainer,
126{
127    fn deref_mut(&mut self) -> &mut Self::Target {
128        self.store_mut()
129    }
130}
131
132impl<A, I, S> core::ops::Index<I> for ContainerBase<S>
133where
134    S: RawContainer<Item = A> + core::ops::Index<I, Output = A>,
135{
136    type Output = S::Item;
137
138    fn index(&self, index: I) -> &Self::Output {
139        self.store().index(index)
140    }
141}
142
143impl<A, I, S> core::ops::IndexMut<I> for ContainerBase<S>
144where
145    S: RawContainer<Item = A> + core::ops::IndexMut<I, Output = A>,
146{
147    fn index_mut(&mut self, index: I) -> &mut Self::Output {
148        self.store_mut().index_mut(index)
149    }
150}
151
152impl<A, S> IntoIterator for ContainerBase<S>
153where
154    S: RawContainer<Item = A> + IntoIterator<Item = A>,
155{
156    type Item = A;
157    type IntoIter = S::IntoIter;
158
159    fn into_iter(self) -> Self::IntoIter {
160        self.repr.into_iter()
161    }
162}
163
164impl<'a, A, S> IntoIterator for &'a ContainerBase<S>
165where
166    S: RawContainer<Item = A>,
167    for<'b> &'b S: IntoIterator<Item = A>,
168{
169    type Item = A;
170    type IntoIter = <&'a S as IntoIterator>::IntoIter;
171
172    fn into_iter(self) -> Self::IntoIter {
173        self.store().into_iter()
174    }
175}
176
177impl<'a, A, S> IntoIterator for &'a mut ContainerBase<S>
178where
179    S: RawContainer<Item = A>,
180    for<'b> &'b mut S: IntoIterator<Item = S::Item>,
181{
182    type Item = A;
183    type IntoIter = <&'a mut S as IntoIterator>::IntoIter;
184
185    fn into_iter(self) -> Self::IntoIter {
186        self.store_mut().into_iter()
187    }
188}