typewit/type_identity.rs
1use crate::TypeEq;
2
3/// Emulation of `T == U` bounds.
4///
5/// This trait emulates `T == U` bounds with `T: Identity<Type = U>`.
6///
7/// # Projection
8///
9/// Because this trait uses [`TypeEq`] for casting between `Self` and [`Self::Type`],
10/// you can transform the arguments of that `TypeEq` to cast any composition of those types,
11/// e.g: cast between `Vec<Self>` and `Vec<Self::Type>`
12///
13/// # Example
14///
15/// ### Type Parameter Alias
16///
17/// (this example requires Rust 1.61.0, because it uses trait bounds in a `const fn`)
18///
19#[cfg_attr(not(feature = "rust_1_61"), doc = "```ignore")]
20#[cfg_attr(feature = "rust_1_61", doc = "```rust")]
21/// use typewit::{Identity, TypeEq};
22///
23/// assert_eq!(foo(3), [3, 3]);
24///
25/// assert_eq!(foo::<&str, 2, _>("hello"), ["hello", "hello"]);
26///
27///
28/// const fn foo<T, const N: usize, R>(val: T) -> R
29/// where
30/// // emulates a `[T; N] == R` bound
31/// [T; N]: Identity<Type = R>,
32/// T: Copy,
33/// {
34/// Identity::TYPE_EQ // returns a `TypeEq<[T; N], R>`
35/// .to_right([val; N]) // casts `[T; N]` to `R`
36/// }
37/// ```
38///
39/// ### Projection
40///
41/// Demonstrating that any projection of `Self` and `Self::Type` can
42/// be casted to each other.
43///
44/// ```rust
45/// use typewit::{Identity, TypeEq, type_fn};
46///
47/// assert_eq!(make_vec::<u8>(), vec![3, 5, 8]);
48///
49/// fn make_vec<T>() -> Vec<T>
50/// where
51/// T: Identity<Type = u8>
52/// {
53/// let te: TypeEq<Vec<T>, Vec<u8>> = T::TYPE_EQ.project::<VecFn>();
54///
55/// te.to_left(vec![3, 5, 8]) // casts `Vec<u8>` to `Vec<T>`
56/// }
57///
58/// type_fn!{
59/// // A type-level function (TypeFn implementor) from `T` to `Vec<T>`
60/// struct VecFn;
61/// impl<T> T => Vec<T>
62/// }
63/// ```
64///
65pub trait Identity {
66 /// The same type as `Self`,
67 /// used to emulate type equality bounds (`T == U`)
68 /// with associated type equality constraints
69 /// (`T: Identity<Type = U>`).
70 type Type: ?Sized;
71
72 /// Proof that `Self` is the same type as `Self::Type`,
73 /// provides methods for casting between `Self` and `Self::Type`.
74 const TYPE_EQ: TypeEq<Self, Self::Type>;
75}
76
77impl<T: ?Sized> Identity for T {
78 type Type = T;
79
80 const TYPE_EQ: TypeEq<Self, Self::Type> = TypeEq::NEW;
81}