From de22b387e394a6cc3634c32e87492b57b2595717 Mon Sep 17 00:00:00 2001 From: Michael Pfaff Date: Mon, 6 Jun 2022 18:25:51 -0400 Subject: [PATCH] Initial commit --- .gitignore | 2 ++ Cargo.toml | 7 +++++ src/lib.rs | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..57182e2 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "eq-type" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" + +[dependencies] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..ffb7895 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,86 @@ +//! A crate that allows declaring an equality bound on two types and coercing between them. +//! +//! # Examples +//! +//! ``` +//! # 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() { } +//! ``` + +mod private { + pub trait Sealed {} +} + +pub trait Is: private::Sealed { + fn coerce(self) -> Rhs + where + Self: Sized, + Rhs: Sized; + + fn rcoerce(rhs: Rhs) -> Self + where + Self: Sized, + Rhs: Sized; +} + +impl private::Sealed for T {} + +impl Is for T { + #[inline(always)] + fn coerce(self) -> T + where + T: Sized, + { + self + } + + #[inline(always)] + fn rcoerce(t: T) -> T + where + T: Sized, + { + t + } +} + +#[cfg(test)] +mod tests { + use super::Is; + + fn forward(t: T) -> U + where + T: Is, + { + t.coerce() + } + + fn backward(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); + } +}