//! A crate that allows declaring an equality bound on two types and coercing between them. //! //! # Examples #![cfg_attr(feature = "__nightly-sugar", doc = r##" ``` # use eq_type::Is; # pub trait ResultExt: Sized + Is> { /// Given any `E` and `EI` that implement `Into`, converts from Result, E> to Result. fn flatten_into(self) -> Result where T: Is>, E: Into, EI: Into, { self.coerce().map_err(|e| e.into()).and_then(|x| x.coerce().map_err(|e| e.into())) } } # # fn main() { } ``` "##)] #![cfg_attr(feature = "__nightly-sugar", feature(trait_alias))] mod private { pub trait Sealed {} } pub trait __Is: private::Sealed { type Rhs: ?Sized; fn coerce(self) -> Self::Rhs where Self: Sized, Self::Rhs: Sized; fn rcoerce(rhs: Self::Rhs) -> Self where Self: Sized, Self::Rhs: Sized; } impl private::Sealed for T {} impl __Is for T { type Rhs = T; #[inline(always)] fn coerce(self) -> T where T: Sized, { self } #[inline(always)] fn rcoerce(t: T) -> T where T: Sized, { t } } #[cfg(feature = "__nightly-sugar")] pub trait Is = __Is; #[cfg(test)] mod tests { use super::__Is; #[cfg(feature = "__nightly-sugar")] use super::Is; fn forward(t: T) -> U where T: __Is, { t.coerce() } fn backward(u: U) -> T where U: __Is, { u.coerce() } #[cfg(feature = "__nightly-sugar")] fn forward_sugar(t: T) -> U where T: Is, { t.coerce() } #[cfg(feature = "__nightly-sugar")] fn backward_sugar(u: U) -> T where U: Is, { u.coerce() } #[test] fn test() { let mut x = 4; x = forward(x); x = backward(x); x = backward(forward(x)); x = forward(backward(x)); assert_eq!(x, 4); } #[cfg(feature = "__nightly-sugar")] #[test] fn test_sugar() { let mut x = 4; x = forward_sugar(x); x = backward_sugar(x); x = backward_sugar(forward_sugar(x)); x = forward_sugar(backward_sugar(x)); assert_eq!(x, 4); } }