freezable/
impls.rs

1use core::cmp::Ordering;
2use core::fmt::{
3    self,
4    Binary,
5    Debug,
6    Display,
7    Formatter,
8    LowerExp,
9    LowerHex,
10    Octal,
11    Pointer,
12    UpperExp,
13    UpperHex,
14};
15use core::hash::{Hash, Hasher};
16use core::iter::Map;
17use core::ops::{
18    Add,
19    BitAnd,
20    BitOr,
21    BitXor,
22    Deref,
23    Div,
24    Index,
25    Mul,
26    Neg,
27    RangeBounds,
28    Rem,
29    Shl,
30    Shr,
31    Sub,
32};
33
34use crate::{Freezable, Frozen, Unfreezable};
35
36impl<T: Freezable + ?Sized> Deref for Frozen<T> {
37    type Target = T::Frozen;
38
39    fn deref(&self) -> &Self::Target {
40        &self.0
41    }
42}
43
44impl<T: Freezable + ?Sized, U> FromIterator<U> for Frozen<T>
45where
46    T: FromIterator<U>,
47{
48    fn from_iter<I: IntoIterator<Item = U>>(iter: I) -> Self {
49        iter.into_iter().collect::<T>().freeze()
50    }
51}
52
53impl<T: Freezable + ?Sized> IntoIterator for Frozen<T>
54where
55    T::Frozen: IntoIterator,
56{
57    type IntoIter = <<T as Freezable>::Frozen as IntoIterator>::IntoIter;
58    type Item = <<T as Freezable>::Frozen as IntoIterator>::Item;
59
60    fn into_iter(self) -> Self::IntoIter {
61        self.0.into_iter()
62    }
63}
64
65impl<T: Freezable + ?Sized> Hash for Frozen<T>
66where
67    T::Frozen: Hash,
68{
69    fn hash<H: Hasher>(&self, state: &mut H) {
70        self.0.hash(state);
71    }
72}
73
74impl<T: Freezable + ?Sized, U> Index<U> for Frozen<T>
75where
76    T::Frozen: Index<U>,
77{
78    type Output = <T::Frozen as Index<U>>::Output;
79
80    fn index(&self, index: U) -> &Self::Output {
81        &self.0[index]
82    }
83}
84
85impl<T: Freezable + ?Sized> Clone for Frozen<T>
86where
87    T::Frozen: Clone,
88{
89    fn clone(&self) -> Self {
90        Frozen(self.0.clone())
91    }
92}
93impl<T: Freezable + ?Sized> Copy for Frozen<T> where T::Frozen: Copy
94{
95}
96impl<T: Freezable + ?Sized> PartialEq for Frozen<T>
97where
98    T::Frozen: PartialEq,
99{
100    fn eq(&self, other: &Self) -> bool {
101        self.0.eq(&other.0)
102    }
103}
104impl<T: Freezable + ?Sized> Eq for Frozen<T> where T::Frozen: Eq
105{
106}
107impl<T: Freezable + ?Sized> PartialOrd for Frozen<T>
108where
109    T::Frozen: PartialOrd,
110{
111    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
112        self.0.partial_cmp(&other.0)
113    }
114}
115impl<T: Freezable + ?Sized> Ord for Frozen<T>
116where
117    T::Frozen: Ord,
118{
119    fn cmp(&self, other: &Self) -> Ordering {
120        self.0.cmp(&other.0)
121    }
122}
123impl<T: Freezable + ?Sized + Default> Default for Frozen<T> {
124    fn default() -> Self {
125        T::default().freeze()
126    }
127}
128impl<T: Freezable + ?Sized> Debug for Frozen<T>
129where
130    T::Frozen: Debug,
131{
132    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
133        write!(f, "Frozen({:?})", self.0)
134    }
135}
136
137macro_rules! impl_fmt {
138    ($trait_name:ident) => {
139        impl<T: Freezable + ?Sized> $trait_name for Frozen<T>
140        where
141            T::Frozen: $trait_name,
142        {
143            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
144                self.0.fmt(f)
145            }
146        }
147    };
148}
149impl_fmt!(Display);
150impl_fmt!(Octal);
151impl_fmt!(LowerHex);
152impl_fmt!(UpperHex);
153impl_fmt!(Pointer);
154impl_fmt!(Binary);
155impl_fmt!(LowerExp);
156impl_fmt!(UpperExp);
157
158macro_rules! impl_op {
159    ($trait_name:ident, $trait_fn:ident) => {
160        impl<T: Freezable + ?Sized, U> $trait_name<U> for Frozen<T>
161        where
162            T::Frozen: $trait_name<U>,
163        {
164            type Output = <T::Frozen as $trait_name<U>>::Output;
165
166            fn $trait_fn(self, rhs: U) -> Self::Output {
167                self.0.$trait_fn(rhs)
168            }
169        }
170        impl<'a, T: Freezable + ?Sized, U> $trait_name<U> for &'a Frozen<T>
171        where
172            &'a T::Frozen: $trait_name<U>,
173        {
174            type Output = <&'a T::Frozen as $trait_name<U>>::Output;
175
176            fn $trait_fn(self, rhs: U) -> Self::Output {
177                (&self.0).$trait_fn(rhs)
178            }
179        }
180    };
181}
182
183macro_rules! impl_ops {
184    ($($trait_name:ident ($trait_fn:ident)),* $(,)?) => {
185        $(impl_op!($trait_name, $trait_fn);)*
186    };
187}
188
189impl_ops!(
190    Add(add),
191    BitAnd(bitand),
192    BitOr(bitor),
193    BitXor(bitxor),
194    Div(div),
195    Mul(mul),
196    Rem(rem),
197    Shl(shl),
198    Shr(shr),
199    Sub(sub),
200);
201
202impl<T: Freezable + ?Sized, U> AsRef<U> for Frozen<T>
203where
204    T::Frozen: AsRef<U>,
205{
206    fn as_ref(&self) -> &U {
207        self.0.as_ref()
208    }
209}
210
211impl<T: Freezable + ?Sized> Neg for Frozen<T>
212where
213    T::Frozen: Neg,
214{
215    type Output = <T::Frozen as Neg>::Output;
216
217    fn neg(self) -> Self::Output {
218        -self.0
219    }
220}
221
222impl<T: Freezable + ?Sized, U> RangeBounds<U> for Frozen<T>
223where
224    T::Frozen: RangeBounds<U>,
225{
226    fn start_bound(&self) -> core::ops::Bound<&U> {
227        self.0.start_bound()
228    }
229
230    fn end_bound(&self) -> core::ops::Bound<&U> {
231        self.0.end_bound()
232    }
233}
234
235impl<T: Freezable + ?Sized> Freezable for Frozen<T> {
236    type Frozen = T::Frozen;
237
238    fn freeze(self) -> Frozen<Self> {
239        Frozen(self.0)
240    }
241}
242
243impl<T: Freezable + ?Sized> Unfreezable<Frozen<T>> for Frozen<T> {
244    fn thaw(wrapped: <Frozen<T> as Freezable>::Frozen) -> Self {
245        Frozen(wrapped)
246    }
247}
248
249pub trait FreezableIteratorExt<T: Freezable>: Iterator<Item = T> + Sized {
250    fn frozen(self) -> Map<Self, fn(T) -> Frozen<T>> {
251        self.map(Freezable::freeze)
252    }
253}
254
255impl<T: Freezable, I: Iterator<Item = T>> FreezableIteratorExt<T> for I {
256}
257
258pub trait UnfreezableIteratorExt<T: Freezable>:
259    Iterator<Item = Frozen<T>> + Sized
260{
261    fn thawed<U: Unfreezable<T>>(self) -> Map<Self, fn(Frozen<T>) -> U> {
262        self.map(Frozen::thaw)
263    }
264}
265impl<T: Freezable, I: Iterator<Item = Frozen<T>>> UnfreezableIteratorExt<T> for I {
266}