1use std::sync::Arc;
2
3use crate::collections::Set;
4
5pub trait To {
6 fn to<T>(&self) -> T
7 where
8 Self: Upcast<T>;
9}
10
11impl<A> To for A {
12 fn to<T>(&self) -> T
13 where
14 Self: Upcast<T>,
15 {
16 <&A as Upcast<T>>::upcast(self)
17 }
18}
19
20pub trait Upcast<T>: Clone {
23 fn upcast(self) -> T;
24}
25
26impl<T, U> Upcast<U> for T
27where
28 T: Clone,
29 U: UpcastFrom<T>,
30{
31 fn upcast(self) -> U {
32 U::upcast_from(self)
33 }
34}
35
36pub trait UpcastFrom<T: Clone> {
39 fn upcast_from(term: T) -> Self;
40}
41
42pub trait Downcast: Sized {
44 fn downcast<T>(&self) -> Option<T>
45 where
46 T: DowncastFrom<Self>;
47
48 fn is_a<T>(&self) -> bool
49 where
50 T: DowncastFrom<Self>,
51 {
52 self.downcast::<T>().is_some()
53 }
54}
55
56impl<U> Downcast for U {
57 fn downcast<T>(&self) -> Option<T>
58 where
59 T: DowncastFrom<Self>,
60 {
61 T::downcast_from(self)
62 }
63}
64
65pub trait DowncastTo<T>: Sized {
73 fn downcast_to(&self) -> Option<T>;
74}
75
76impl<T: Clone, U> DowncastTo<T> for &U
77where
78 T: DowncastFrom<U>,
79{
80 fn downcast_to(&self) -> Option<T> {
81 T::downcast_from(self)
82 }
83}
84
85impl<A, B> DowncastTo<Vec<B>> for Vec<A>
86where
87 B: DowncastFrom<A>,
88{
89 fn downcast_to(&self) -> Option<Vec<B>> {
90 self.iter().map(|a| B::downcast_from(a)).collect()
91 }
92}
93
94pub trait DowncastFrom<T>: Sized {
101 fn downcast_from(t: &T) -> Option<Self>;
102}
103
104impl<T, U> DowncastFrom<T> for U
105where
106 T: DowncastTo<U>,
107{
108 fn downcast_from(t: &T) -> Option<U> {
109 t.downcast_to()
110 }
111}
112
113impl<A, B> DowncastFrom<Set<A>> for Set<B>
114where
115 A: Ord,
116 B: DowncastFrom<A> + Ord,
117{
118 fn downcast_from(t: &Set<A>) -> Option<Self> {
119 t.iter().map(|a| B::downcast_from(a)).collect()
120 }
121}
122
123impl<T, U> DowncastFrom<Option<U>> for Option<T>
124where
125 T: DowncastFrom<U>,
126{
127 fn downcast_from(u: &Option<U>) -> Option<Self> {
128 match u {
129 Some(u) => Some(Some(T::downcast_from(u)?)),
130 None => None,
131 }
132 }
133}
134
135impl<T, U> DowncastFrom<Arc<U>> for Arc<T>
136where
137 T: DowncastFrom<U>,
138{
139 fn downcast_from(u: &Arc<U>) -> Option<Self> {
140 let t: T = T::downcast_from(u)?;
141 Some(Arc::new(t))
142 }
143}
144
145impl<A, B, A1, B1> DowncastFrom<(A1, B1)> for (A, B)
146where
147 A: DowncastFrom<A1>,
148 B: DowncastFrom<B1>,
149{
150 fn downcast_from(term: &(A1, B1)) -> Option<Self> {
151 let (a1, b1) = term;
152 let a = DowncastFrom::downcast_from(a1)?;
153 let b = DowncastFrom::downcast_from(b1)?;
154 Some((a, b))
155 }
156}
157
158impl<A, B, C, A1, B1, C1> DowncastFrom<(A1, B1, C1)> for (A, B, C)
159where
160 A: DowncastFrom<A1>,
161 B: DowncastFrom<B1>,
162 C: DowncastFrom<C1>,
163{
164 fn downcast_from(term: &(A1, B1, C1)) -> Option<Self> {
165 let (a1, b1, c1) = term;
166 let a = DowncastFrom::downcast_from(a1)?;
167 let b = DowncastFrom::downcast_from(b1)?;
168 let c = DowncastFrom::downcast_from(c1)?;
169 Some((a, b, c))
170 }
171}
172
173impl<T: Clone, U> UpcastFrom<&T> for U
174where
175 T: Upcast<U>,
176{
177 fn upcast_from(term: &T) -> Self {
178 T::upcast(T::clone(term))
179 }
180}
181
182impl<T: Clone, U> UpcastFrom<Vec<T>> for Vec<U>
183where
184 T: Upcast<U>,
185{
186 fn upcast_from(term: Vec<T>) -> Self {
187 term.into_iter().map(|t| T::upcast(t)).collect()
188 }
189}
190
191impl<T: Clone, U> UpcastFrom<Set<T>> for Set<U>
192where
193 T: Upcast<U> + Ord,
194 U: Ord,
195{
196 fn upcast_from(term: Set<T>) -> Self {
197 term.into_iter().map(|t| T::upcast(t)).collect()
198 }
199}
200
201impl<T: Clone, U> UpcastFrom<&[T]> for Vec<U>
202where
203 T: Upcast<U>,
204{
205 fn upcast_from(term: &[T]) -> Self {
206 term.iter().map(|t| t.upcast()).collect()
207 }
208}
209
210impl<T: Clone, U> UpcastFrom<Option<T>> for Option<U>
211where
212 T: Upcast<U>,
213{
214 fn upcast_from(term: Option<T>) -> Self {
215 term.map(|t| t.upcast())
216 }
217}
218
219impl DowncastTo<()> for () {
220 fn downcast_to(&self) -> Option<()> {
221 Some(())
222 }
223}
224
225impl<T> UpcastFrom<()> for T
226where
227 T: Default,
228{
229 fn upcast_from((): ()) -> Self {
230 Default::default()
231 }
232}
233
234impl<T: Clone, U> UpcastFrom<Arc<T>> for Arc<U>
235where
236 T: Upcast<U>,
237{
238 fn upcast_from(term: Arc<T>) -> Self {
239 let term: &T = &term;
240 Arc::new(term.to())
241 }
242}
243
244impl<A, B, A1, B1> UpcastFrom<(A1, B1)> for (A, B)
245where
246 A1: Upcast<A>,
247 B1: Upcast<B>,
248{
249 fn upcast_from(term: (A1, B1)) -> Self {
250 let (a1, b1) = term;
251 (a1.upcast(), b1.upcast())
252 }
253}
254
255impl<A, B, C, A1, B1, C1> UpcastFrom<(A1, B1, C1)> for (A, B, C)
256where
257 A1: Upcast<A>,
258 B1: Upcast<B>,
259 C1: Upcast<C>,
260{
261 fn upcast_from(term: (A1, B1, C1)) -> Self {
262 let (a1, b1, c1) = term;
263 (a1.upcast(), b1.upcast(), c1.upcast())
264 }
265}
266
267impl<A, As, B, Bs, Z> UpcastFrom<(A, B)> for Vec<Z>
268where
269 A: IntoIterator<Item = As> + Clone,
270 As: Upcast<Z>,
271 B: IntoIterator<Item = Bs> + Clone,
272 Bs: Upcast<Z>,
273{
274 fn upcast_from(term: (A, B)) -> Self {
275 let (a, b) = term;
276 let mut v: Self = vec![];
277 v.extend(a.into_iter().map(|a| a.upcast()));
278 v.extend(b.into_iter().map(|b| b.upcast()));
279 v
280 }
281}
282
283impl<A, B, C, Z> UpcastFrom<(A, B, C)> for Vec<Z>
284where
285 A: Upcast<Z>,
286 B: Upcast<Z>,
287 C: Upcast<Z>,
288{
289 fn upcast_from(term: (A, B, C)) -> Self {
290 let (a, b, c) = term;
291 vec![a.upcast(), b.upcast(), c.upcast()]
292 }
293}
294
295#[macro_export]
296macro_rules! cast_impl {
297 ($e:ident :: $v:ident ($u:ty)) => {
298 impl $crate::UpcastFrom<$u> for $e {
299 fn upcast_from(v: $u) -> $e {
300 $e::$v(v)
301 }
302 }
303
304 impl $crate::DowncastTo<$u> for $e {
305 fn downcast_to(&self) -> Option<$u> {
306 match self {
307 $e::$v(u) => Some(Clone::clone(u)),
308 _ => None,
309 }
310 }
311 }
312 };
313
314 (impl($($p:tt)*) $e:ident ($($ep:tt)*) :: $v:ident ($u:ty)) => {
315 impl<$($p)*> $crate::UpcastFrom<$u> for $e<$($ep)*> {
316 fn upcast_from(v: $u) -> $e<$($ep)*> {
317 $e::$v(v)
318 }
319 }
320
321 impl<$($p)*> $crate::DowncastTo<$u> for $e<$($ep)*> {
322 fn downcast_to(&self) -> Option<$u> {
323 match self {
324 $e::$v(u) => Some(Clone::clone(u)),
325 _ => None,
326 }
327 }
328 }
329 };
330
331 (impl($($p:tt)*) $t:ty) => {
332 impl<$($p)*> $crate::UpcastFrom<$t> for $t {
333 fn upcast_from(v: $t) -> $t {
334 v
335 }
336 }
337
338 impl<$($p)*> $crate::DowncastTo<$t> for $t {
339 fn downcast_to(&self) -> Option<$t> {
340 Some(Self::clone(self))
341 }
342 }
343 };
344
345 ($t:ty) => {
346 impl $crate::UpcastFrom<$t> for $t {
347 fn upcast_from(v: $t) -> $t {
348 v
349 }
350 }
351
352 impl $crate::DowncastTo<$t> for $t {
353 fn downcast_to(&self) -> Option<$t> {
354 Some(Self::clone(self))
355 }
356 }
357 };
358
359 ($(impl($($p:tt)*))? ($bot:ty) <: ($($mid:ty),*) <: ($top:ty)) => {
360 impl$(<$($p)*>)? $crate::UpcastFrom<$bot> for $top {
361 fn upcast_from(v: $bot) -> $top {
362 $(
363 let v: $mid = $crate::Upcast::upcast(v);
364 )*
365 $crate::Upcast::upcast(v)
366 }
367 }
368
369 impl$(<$($p)*>)? $crate::DowncastTo<$bot> for $top {
370 fn downcast_to(&self) -> Option<$bot> {
371 let v: &$top = self;
372 $(
373 let v: &$mid = &$crate::DowncastFrom::downcast_from(v)?;
374 )*
375 $crate::DowncastFrom::downcast_from(v)
376 }
377 }
378 };
379}
380
381cast_impl!(usize);
382cast_impl!(u32);
383cast_impl!(String);
384
385impl UpcastFrom<&str> for String {
386 fn upcast_from(term: &str) -> Self {
387 term.into()
388 }
389}
390
391pub trait Upcasted<'a, T> {
392 fn upcasted(self) -> Box<dyn Iterator<Item = T> + 'a>;
393}
394
395impl<'a, T, I> Upcasted<'a, T> for I
396where
397 I: IntoIterator + 'a,
398 I::Item: Upcast<T>,
399{
400 fn upcasted(self) -> Box<dyn Iterator<Item = T> + 'a> {
401 Box::new(self.into_iter().map(|e| e.upcast()))
402 }
403}
404
405pub trait Downcasted<'a>: IntoIterator {
406 fn downcasted<T>(self) -> Box<dyn Iterator<Item = T> + 'a>
407 where
408 T: DowncastFrom<Self::Item>;
409}
410
411impl<'a, I> Downcasted<'a> for I
412where
413 I: IntoIterator + 'a,
414{
415 fn downcasted<T>(self) -> Box<dyn Iterator<Item = T> + 'a>
416 where
417 T: DowncastFrom<I::Item>,
418 {
419 Box::new(self.into_iter().filter_map(|e| T::downcast_from(&e)))
420 }
421}