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}