pub const fn type_eq<T: ?Sized>() -> TypeEq<T, T>
Expand description
Constructs a TypeEq<T, T>
§Example
use typewit::{MakeTypeWitness, TypeWitnessTypeArg, TypeEq, type_eq};
assert_eq!(ascii_to_upper(b'a'), b'A');
assert_eq!(ascii_to_upper(b'f'), b'F');
assert_eq!(ascii_to_upper(b'B'), b'B');
assert_eq!(ascii_to_upper(b'0'), b'0');
assert_eq!(ascii_to_upper('c'), 'C');
assert_eq!(ascii_to_upper('e'), 'E');
assert_eq!(ascii_to_upper('H'), 'H');
assert_eq!(ascii_to_upper('@'), '@');
const fn ascii_to_upper<T>(c: T) -> T
where
Wit<T>: MakeTypeWitness,
{
match MakeTypeWitness::MAKE {
Wit::U8(te) => {
// `te` is a `TypeEq<T, u8>`, which allows casting between `T` and `u8`.
// `te.to_right(...)` goes from `T` to `u8`
// `te.to_left(...)` goes from `u8` to `T`
te.to_left(te.to_right(c).to_ascii_uppercase())
}
Wit::Char(te) => {
// `te` is a `TypeEq<T, char>`, which allows casting between `T` and `char`.
// `te.to_right(...)` goes from `T` to `char`
// `te.to_left(...)` goes from `char` to `T`
te.to_left(te.to_right(c).to_ascii_uppercase())
}
}
}
// This is a type witness
enum Wit<T> {
// this variant requires `T == u8`
U8(TypeEq<T, u8>),
// this variant requires `T == char`
Char(TypeEq<T, char>),
}
impl<T> TypeWitnessTypeArg for Wit<T> {
type Arg = T;
}
impl MakeTypeWitness for Wit<u8> {
const MAKE: Self = Self::U8(type_eq());
}
impl MakeTypeWitness for Wit<char> {
const MAKE: Self = Self::Char(type_eq());
}
The code above can be written more concisly using
the polymatch
and simple_type_witness
macros:
const fn ascii_to_upper<T>(c: T) -> T
where
Wit<T>: MakeTypeWitness,
{
// deduplicating identical match arms using the `polymatch` macro.
typewit::polymatch!{MakeTypeWitness::MAKE;
Wit::U8(te) | Wit::Char(te) => te.to_left(te.to_right(c).to_ascii_uppercase())
}
}
// This macro declares a type witness
typewit::simple_type_witness! {
// Declares `enum Wit<__Wit>`
// The `__Wit` type parameter is implicit and always the last generic parameter.
enum Wit {
// this variant requires `__Wit == u8`
U8 = u8,
// this variant requires `__Wit == char`
Char = char,
}
}
note that simple_type_witness
can’t replace enums whose
witnessed type parameter is not the last,
or have variants with anything but one TypeEq
field each.