From 4d9dec9401a8cdd445346fe93bbd7e434bd4b82f Mon Sep 17 00:00:00 2001 From: Michael Pfaff Date: Sun, 21 Aug 2022 10:43:32 -0400 Subject: [PATCH] Improved API --- Cargo.toml | 8 ++++- src/lib.rs | 93 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 73 insertions(+), 28 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 038cbfd..6d6c3f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "eq-type" -version = "0.1.0" +version = "0.2.0" authors = ["Michael "] license = "MIT OR Apache-2.0" description = "Allows declaring an equality bound on two types and coercing between them." @@ -9,4 +9,10 @@ homepage = "https://git.pfaff.dev/michael/eq-type.rs" readme = "README.md" edition = "2021" +[features] +default = [ "__nightly-sugar" ] + +__nightly-sugar = [ ] +nightly = [ "__nightly-sugar" ] + [dependencies] diff --git a/src/lib.rs b/src/lib.rs index ffb7895..de5896a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,44 +1,51 @@ //! 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() { } -//! ``` +#![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 { - fn coerce(self) -> Rhs - where - Self: Sized, - Rhs: Sized; +pub trait __Is: private::Sealed { + type Rhs: ?Sized; - fn rcoerce(rhs: Rhs) -> Self + fn coerce(self) -> Self::Rhs where Self: Sized, - Rhs: 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 { +impl __Is for T { + type Rhs = T; + #[inline(always)] fn coerce(self) -> T where @@ -56,18 +63,39 @@ impl Is for 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() } - fn backward(u: U) -> T + #[cfg(feature = "__nightly-sugar")] + fn backward_sugar(u: U) -> T where U: Is, { @@ -83,4 +111,15 @@ mod tests { 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); + } }