Skip to content

Commit

Permalink
add private Try traits
Browse files Browse the repository at this point in the history
  • Loading branch information
yoshuawuyts committed Mar 17, 2024
1 parent a4f6d50 commit a1695a6
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 175 deletions.
175 changes: 0 additions & 175 deletions src/concurrent_stream/try_for_each.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,178 +248,3 @@ mod test {
});
}
}

// /// We hide the `Try` trait in a private module, as it's only meant to be a
// /// stable clone of the standard library's `Try` trait, as yet unstable.
// // NOTE: copied from `rayon`
// mod private {
// use std::convert::Infallible;
// use std::ops::ControlFlow::{self, Break, Continue};
// use std::task::Poll;

// /// Clone of `std::ops::Try`.
// ///
// /// Implementing this trait is not permitted outside of `futures_concurrency`.
// pub trait Try {
// private_decl! {}

// type Output;
// type Residual;

// fn from_output(output: Self::Output) -> Self;

// fn from_residual(residual: Self::Residual) -> Self;

// fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
// }

// impl<B, C> Try for ControlFlow<B, C> {
// private_impl! {}

// type Output = C;
// type Residual = ControlFlow<B, Infallible>;

// fn from_output(output: Self::Output) -> Self {
// Continue(output)
// }

// fn from_residual(residual: Self::Residual) -> Self {
// match residual {
// Break(b) => Break(b),
// Continue(_) => unreachable!(),
// }
// }

// fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
// match self {
// Continue(c) => Continue(c),
// Break(b) => Break(Break(b)),
// }
// }
// }

// impl<T> Try for Option<T> {
// private_impl! {}

// type Output = T;
// type Residual = Option<Infallible>;

// fn from_output(output: Self::Output) -> Self {
// Some(output)
// }

// fn from_residual(residual: Self::Residual) -> Self {
// match residual {
// None => None,
// Some(_) => unreachable!(),
// }
// }

// fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
// match self {
// Some(c) => Continue(c),
// None => Break(None),
// }
// }
// }

// impl<T, E> Try for Result<T, E> {
// private_impl! {}

// type Output = T;
// type Residual = Result<Infallible, E>;

// fn from_output(output: Self::Output) -> Self {
// Ok(output)
// }

// fn from_residual(residual: Self::Residual) -> Self {
// match residual {
// Err(e) => Err(e),
// Ok(_) => unreachable!(),
// }
// }

// fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
// match self {
// Ok(c) => Continue(c),
// Err(e) => Break(Err(e)),
// }
// }
// }

// impl<T, E> Try for Poll<Result<T, E>> {
// private_impl! {}

// type Output = Poll<T>;
// type Residual = Result<Infallible, E>;

// fn from_output(output: Self::Output) -> Self {
// output.map(Ok)
// }

// fn from_residual(residual: Self::Residual) -> Self {
// match residual {
// Err(e) => Poll::Ready(Err(e)),
// Ok(_) => unreachable!(),
// }
// }

// fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
// match self {
// Poll::Pending => Continue(Poll::Pending),
// Poll::Ready(Ok(c)) => Continue(Poll::Ready(c)),
// Poll::Ready(Err(e)) => Break(Err(e)),
// }
// }
// }

// impl<T, E> Try for Poll<Option<Result<T, E>>> {
// private_impl! {}

// type Output = Poll<Option<T>>;
// type Residual = Result<Infallible, E>;

// fn from_output(output: Self::Output) -> Self {
// match output {
// Poll::Ready(o) => Poll::Ready(o.map(Ok)),
// Poll::Pending => Poll::Pending,
// }
// }

// fn from_residual(residual: Self::Residual) -> Self {
// match residual {
// Err(e) => Poll::Ready(Some(Err(e))),
// Ok(_) => unreachable!(),
// }
// }

// fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
// match self {
// Poll::Pending => Continue(Poll::Pending),
// Poll::Ready(None) => Continue(Poll::Ready(None)),
// Poll::Ready(Some(Ok(c))) => Continue(Poll::Ready(Some(c))),
// Poll::Ready(Some(Err(e))) => Break(Err(e)),
// }
// }
// }

// #[allow(missing_debug_implementations)]
// pub struct PrivateMarker;
// macro_rules! private_impl {
// () => {
// fn __futures_concurrency_private__(&self) -> crate::private::PrivateMarker {
// crate::private::PrivateMarker
// }
// };
// }

// macro_rules! private_decl {
// () => {
// /// This trait is private; this method exists to make it
// /// impossible to implement outside the crate.
// #[doc(hidden)]
// fn __futures_concurrency_private__(&self) -> crate::private::PrivateMarker;
// };
// }
// }
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ extern crate alloc;

mod utils;

#[doc(hidden)]
pub use utils::private;

/// The futures concurrency prelude.
pub mod prelude {
pub use super::future::FutureExt as _;
Expand Down
3 changes: 3 additions & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ mod poll_state;
mod tuple;
mod wakers;

#[doc(hidden)]
pub mod private;

pub(crate) use self::futures::FutureArray;
#[cfg(feature = "alloc")]
pub(crate) use self::futures::FutureVec;
Expand Down
179 changes: 179 additions & 0 deletions src/utils/private.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/// We hide the `Try` trait in a private module, as it's only meant to be a
/// stable clone of the standard library's `Try` trait, as yet unstable.
// NOTE: copied from `rayon`
use std::convert::Infallible;

Check failure on line 4 in src/utils/private.rs

View workflow job for this annotation

GitHub Actions / Build and test (ubuntu-latest, stable)

failed to resolve: use of undeclared crate or module `std`
use std::ops::ControlFlow::{self, Break, Continue};

Check failure on line 5 in src/utils/private.rs

View workflow job for this annotation

GitHub Actions / Build and test (ubuntu-latest, stable)

failed to resolve: use of undeclared crate or module `std`
use std::task::Poll;

Check failure on line 6 in src/utils/private.rs

View workflow job for this annotation

GitHub Actions / Build and test (ubuntu-latest, stable)

failed to resolve: use of undeclared crate or module `std`

use crate::{private_decl, private_impl};

/// Clone of `std::ops::Try`.
///
/// Implementing this trait is not permitted outside of `futures_concurrency`.
pub trait Try {
private_decl! {}

type Output;
type Residual;

fn from_output(output: Self::Output) -> Self;

fn from_residual(residual: Self::Residual) -> Self;

fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
}

impl<B, C> Try for ControlFlow<B, C> {
private_impl! {}

type Output = C;
type Residual = ControlFlow<B, Infallible>;

fn from_output(output: Self::Output) -> Self {
Continue(output)
}

fn from_residual(residual: Self::Residual) -> Self {
match residual {
Break(b) => Break(b),
Continue(_) => unreachable!(),
}
}

fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
match self {
Continue(c) => Continue(c),
Break(b) => Break(Break(b)),
}
}
}

impl<T> Try for Option<T> {
private_impl! {}

type Output = T;
type Residual = Option<Infallible>;

fn from_output(output: Self::Output) -> Self {
Some(output)
}

fn from_residual(residual: Self::Residual) -> Self {
match residual {
None => None,
Some(_) => unreachable!(),
}
}

fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
match self {
Some(c) => Continue(c),
None => Break(None),
}
}
}

impl<T, E> Try for Result<T, E> {
private_impl! {}

type Output = T;
type Residual = Result<Infallible, E>;

fn from_output(output: Self::Output) -> Self {
Ok(output)
}

fn from_residual(residual: Self::Residual) -> Self {
match residual {
Err(e) => Err(e),
Ok(_) => unreachable!(),
}
}

fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
match self {
Ok(c) => Continue(c),
Err(e) => Break(Err(e)),
}
}
}

impl<T, E> Try for Poll<Result<T, E>> {
private_impl! {}

type Output = Poll<T>;
type Residual = Result<Infallible, E>;

fn from_output(output: Self::Output) -> Self {
output.map(Ok)
}

fn from_residual(residual: Self::Residual) -> Self {
match residual {
Err(e) => Poll::Ready(Err(e)),
Ok(_) => unreachable!(),
}
}

fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
match self {
Poll::Pending => Continue(Poll::Pending),
Poll::Ready(Ok(c)) => Continue(Poll::Ready(c)),
Poll::Ready(Err(e)) => Break(Err(e)),
}
}
}

impl<T, E> Try for Poll<Option<Result<T, E>>> {
private_impl! {}

type Output = Poll<Option<T>>;
type Residual = Result<Infallible, E>;

fn from_output(output: Self::Output) -> Self {
match output {
Poll::Ready(o) => Poll::Ready(o.map(Ok)),
Poll::Pending => Poll::Pending,
}
}

fn from_residual(residual: Self::Residual) -> Self {
match residual {
Err(e) => Poll::Ready(Some(Err(e))),
Ok(_) => unreachable!(),
}
}

fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
match self {
Poll::Pending => Continue(Poll::Pending),
Poll::Ready(None) => Continue(Poll::Ready(None)),
Poll::Ready(Some(Ok(c))) => Continue(Poll::Ready(Some(c))),
Poll::Ready(Some(Err(e))) => Break(Err(e)),
}
}
}

#[allow(missing_debug_implementations)]
pub struct PrivateMarker;

#[doc(hidden)]
#[macro_export]
macro_rules! private_impl {
() => {
fn __futures_concurrency_private__(&self) -> crate::private::PrivateMarker {
crate::private::PrivateMarker
}
};
}

#[doc(hidden)]
#[macro_export]
macro_rules! private_decl {
() => {
/// This trait is private; this method exists to make it
/// impossible to implement outside the crate.
#[doc(hidden)]
fn __futures_concurrency_private__(&self) -> crate::private::PrivateMarker;
};
}

0 comments on commit a1695a6

Please sign in to comment.