pub const fn type_eq<Lhs, Rhs>(_: Lhs, _: Rhs) -> TypeCmp<Lhs, Rhs>Expand description
Compares two IsTStrs for equality,
returning a proof of the (in)equality of the arguments.
This is a non-associated function for const compatibility,
the (non-const) trait method equivalent of this is IsTStr::type_eq
ยงExample
use tstr::{IsTStr, TStr, TS, ts};
use tstr::typewit::TypeCmp;
assert_eq!(is_right_guess(Guess(ts!(foo))), None);
assert_eq!(is_right_guess(Guess(ts!(bar))), None);
assert_eq!(is_right_guess(Guess(ts!(world))), None);
assert!(is_right_guess(Guess(ts!(hello))).is_some_and(|x| x.0 == "hello"));
#[derive(Debug, PartialEq, Eq)]
struct Guess<S: IsTStr>(S);
const fn is_right_guess<S: IsTStr>(guess: Guess<S>) -> Option<Guess<impl IsTStr>> {
match typecast_guess(guess) {
Ok(ret @ Guess::<TS!(hello)>{..}) => Some(ret),
Err(_) => None,
}
}
/// Coerces `Guess<A>` to `Guess<B>` if `A == B`, returns `Err(guess)` if `A != B`.
const fn typecast_guess<A, B>(guess: Guess<A>) -> Result<Guess<B>, Guess<A>>
where
A: IsTStr,
B: IsTStr,
{
tstr::typewit::type_fn!{
// type-level function from `S` to `Guess<S>`
struct GuessFn;
impl<S: IsTStr> S => Guess<S>
}
match tstr::type_eq(A::VAL, B::VAL) {
TypeCmp::Eq(te) => Ok(
// te is a `TypeEq<A, B>`, a value-level proof that both args are the same type.
te
.map(GuessFn) // : TypeEq<Guess<A>, Guess<B>>
.to_right(guess) // : Guess<B>
),
TypeCmp::Ne(_) => Err(guess),
}
}