//! Module defining an Either type. use std::{
future::Future,
io::SeekFrom,
pin::Pin,
task::{Context, Poll},
}; use tokio::io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, ReadBuf, Result};
/// Combines two different futures, streams, or sinks having the same associated types into a single type. /// /// This type implements common asynchronous traits such as [`Future`] and those in Tokio. /// /// [`Future`]: std::future::Future /// /// # Example /// /// The following code will not work: /// /// ```compile_fail /// # fn some_condition() -> bool { true } /// # async fn some_async_function() -> u32 { 10 } /// # async fn other_async_function() -> u32 { 20 } /// #[tokio::main] /// async fn main() { /// let result = if some_condition() { /// some_async_function() /// } else { /// other_async_function() // <- Will print: "`if` and `else` have incompatible types" /// }; /// /// println!("Result is {}", result.await); /// } /// ``` /// // This is because although the output types for both futures is the same, the exact future // types are different, but the compiler must be able to choose a single type for the // `result` variable. /// /// When the output type is the same, we can wrap each future in `Either` to avoid the /// issue: /// /// ``` /// use tokio_util::either::Either; /// # fn some_condition() -> bool { true } /// # async fn some_async_function() -> u32 { 10 } /// # async fn other_async_function() -> u32 { 20 } /// /// #[tokio::main] /// async fn main() { /// let result = if some_condition() { /// Either::Left(some_async_function()) /// } else { /// Either::Right(other_async_function()) /// }; /// /// let value = result.await; /// println!("Result is {}", value); /// # assert_eq!(value, 10); /// } /// ``` #[allow(missing_docs)] // Doc-comments for variants in this particular case don't make much sense. #[derive(Debug, Clone)] pubenum Either<L, R> {
Left(L),
Right(R),
}
/// A small helper macro which reduces amount of boilerplate in the actual trait method implementation. /// It takes an invocation of method as an argument (e.g. `self.poll(cx)`), and redirects it to either /// enum variant held in `self`.
macro_rules! delegate_call {
($self:ident.$method:ident($($args:ident),+)) => { unsafe { match $self.get_unchecked_mut() { Self::Left(l) => Pin::new_unchecked(l).$method($($args),+), Self::Right(r) => Pin::new_unchecked(r).$method($($args),+),
}
}
}
}
impl<L, R, O> Future for Either<L, R> where
L: Future<Output = O>,
R: Future<Output = O>,
{ type Output = O;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.