Enum spirit_tokio::either::Either [−][src]
pub enum Either<A, B> {
A(A),
B(B),
}
Expand description
The Either
type allows to wrap two similar Fragment
s and let the user choose
which one will be used.
For example, if your server could run both on common TCP and unix domain stream sockets, you
could use the Either<TcpListen, UnixListen>
. This fragment would then create resources of
type Either<TcpListener, UnixListener>
.
Many traits are delegated through to one or the other instance inside (in case both implement
it). So, the above resource will implement the Accept
trait that will accept
instances of Either<TcpStream, UnixStream>
. These’ll in turn implement AsyncRead
and
AsyncWrite
, therefore can be handled uniformly just as connections.
Deserialization
This uses the untagged serde attribute. This means there are no additional configuration
options present and the choice is made by trying to first deserialize the A
variant and
if that fails, trying the B
one. Therefore, the inner resource configs need to have some
distinct fields. In our example, this would parse as TcpListen
:
[[listen]]
port = 1234
While this as an UnixListen
:
[[listen]]
path = "/tmp/socket"
If you need different parsing, you can use either a newtype or remote derive.
Other similar types
This is not the only Either
type around. Unfortunately, none of the available ones was just
right for the use case here, so this crate rolls its own. But it provides From
/Into
conversions between them, if the corresponding feature on this crate is enabled.
More than two options
This allows only two variants. However, if you need more, it is possible to nest them and form a tree.
Drawbacks
Due to the complexity of implementation, the Fragment
is implemented for either only if
both variants are Fragment
s with simple enough Driver
s (drivers that don’t sub-divide
their Fragment
s). Therefore, Vec<Either<TcpListen, UnixListen>>
will work, but
Either<Vec<TcpListen>, Vec<UnixListen>>
will not.
This is an implementation limitation and may be lifted in the future (PRs are welcome).
Examples
use std::sync::Arc;
use serde::Deserialize;
use spirit::{AnyError, Empty, Pipeline, Spirit};
use spirit::prelude::*;
#[cfg(unix)]
use spirit_tokio::either::Either;
use spirit_tokio::handlers::PerConnection;
use spirit_tokio::net::TcpListen;
#[cfg(unix)]
use spirit_tokio::net::unix::UnixListen;
use tokio::io::{AsyncWrite, AsyncWriteExt};
use tokio::pin;
// If we want to work on systems that don't have unix domain sockets...
#[cfg(unix)]
type Listener = Either<TcpListen, UnixListen>;
#[cfg(not(unix))]
type Listener = TcpListen;
const DEFAULT_CONFIG: &str = r#"
[[listening_socket]]
port = 1235
max-conn = 20
error-sleep = "100ms"
"#;
#[derive(Default, Deserialize)]
struct Config {
listening_socket: Vec<Listener>,
}
impl Config {
fn listen(&self) -> Vec<Listener> {
self.listening_socket.clone()
}
}
async fn handle_connection<C: AsyncWrite>(conn: C) -> Result<(), AnyError> {
pin!(conn);
conn.write_all(b"hello world").await?;
conn.shutdown().await?;
Ok(())
}
fn main() {
let handler = PerConnection(|conn, _cfg: &_| async {
if let Err(e) = handle_connection(conn).await {
eprintln!("Error: {}", e);
}
});
Spirit::<Empty, Config>::new()
.config_defaults(DEFAULT_CONFIG)
.with(Pipeline::new("listen").extract_cfg(Config::listen).transform(handler))
.run(|spirit| {
Ok(())
});
}
Variants
Implementations
Extracts the inner value in case both have the same type.
Sometimes, a series of operations produces an Either
with both types the same. In such
case, Either
plays no role anymore and this method can be used to get to the inner value.
Trait Implementations
type Connection = Either<A::Connection, B::Connection>
type Connection = Either<A::Connection, B::Connection>
The type of the accepted connection.
fn poll_accept(
self: Pin<&mut Self>,
ctx: &mut Context<'_>
) -> Poll<Result<Self::Connection, IoError>>
fn poll_accept(
self: Pin<&mut Self>,
ctx: &mut Context<'_>
) -> Poll<Result<Self::Connection, IoError>>
Poll for availability of the next connection. Read more
fn accept(self: Pin<&mut Self>) -> AcceptFuture<'_, Self>ⓘNotable traits for AcceptFuture<'_, A>impl<A: Accept> Future for AcceptFuture<'_, A> type Output = Result<A::Connection, IoError>;
fn accept(self: Pin<&mut Self>) -> AcceptFuture<'_, Self>ⓘNotable traits for AcceptFuture<'_, A>impl<A: Accept> Future for AcceptFuture<'_, A> type Output = Result<A::Connection, IoError>;
impl<A: Accept> Future for AcceptFuture<'_, A> type Output = Result<A::Connection, IoError>;
Accept the next connection. Read more
Attempts to return the contents of the internal buffer, filling it with more data from the inner reader if it is empty. Read more
Attempt to write bytes from buf
into the object. Read more
Attempts to flush the object, ensuring that any buffered data reach their destination. Read more
Initiates or attempts to shut down this writer, returning success when the I/O connection has completely shut down. Read more
Like poll_write
, except that it writes from a slice of buffers. Read more
Determines if this writer has an efficient poll_write_vectored
implementation. Read more
impl<A, B, AR, BR> Comparable<Either<AR, BR>> for Either<A, B> where
A: Comparable<AR>,
B: Comparable<BR>,
impl<A, B, AR, BR> Comparable<Either<AR, BR>> for Either<A, B> where
A: Comparable<AR>,
B: Comparable<BR>,
Compares two fragments.
impl<'de, A, B> Deserialize<'de> for Either<A, B> where
A: Deserialize<'de>,
B: Deserialize<'de>,
impl<'de, A, B> Deserialize<'de> for Either<A, B> where
A: Deserialize<'de>,
B: Deserialize<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error> where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error> where
__D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
type SubFragment = Either<A, B>
type SubFragment = Either<A, B>
fn instructions<T, I>(
&mut self,
fragment: &Either<A, B>,
transform: &mut T,
name: &'static str
) -> Result<Vec<Instruction<T::OutputResource>>, Vec<AnyError>> where
T: Transformation<<Self::SubFragment as Fragment>::Resource, I, Self::SubFragment>,
fn instructions<T, I>(
&mut self,
fragment: &Either<A, B>,
transform: &mut T,
name: &'static str
) -> Result<Vec<Instruction<T::OutputResource>>, Vec<AnyError>> where
T: Transformation<<Self::SubFragment as Fragment>::Resource, I, Self::SubFragment>,
Issues the instructions how to transition to the new fragment. Read more
Call to this method informs the Driver
that the instructions returned by the last call
to instructions
were followed and the changes have taken place. Read more
Call to this method informs the Driver
that the instructions returned by the last call
to instructions
were not followed and were dropped. Read more
type Driver = EitherDriver<A, B>
type Driver = EitherDriver<A, B>
The default driver to be used by the fragment. Read more
type Installer = EitherInstaller<A::Installer, B::Installer>
type Installer = EitherInstaller<A::Installer, B::Installer>
The default installer to be used unless a transformation or the user doesn’t provide one. Read more
Runs the first stage of creation. Read more
Runs the second stage of creation. Read more
Configuration if the pipeline should be run once even before the config is loaded. Read more
Runs both stages of creation at once. Read more
fn init<B>(
builder: B,
&'static str
) -> Result<B, Box<dyn Error + Send + Sync + 'static, Global>> where
B: Extensible<Ok = B>,
<B as Extensible>::Config: 'static,
<B as Extensible>::Config: DeserializeOwned,
<B as Extensible>::Config: Send,
<B as Extensible>::Config: Sync,
<B as Extensible>::Opts: 'static,
<B as Extensible>::Opts: StructOpt,
<B as Extensible>::Opts: Send,
<B as Extensible>::Opts: Sync,
fn init<B>(
builder: B,
&'static str
) -> Result<B, Box<dyn Error + Send + Sync + 'static, Global>> where
B: Extensible<Ok = B>,
<B as Extensible>::Config: 'static,
<B as Extensible>::Config: DeserializeOwned,
<B as Extensible>::Config: Send,
<B as Extensible>::Config: Sync,
<B as Extensible>::Opts: 'static,
<B as Extensible>::Opts: StructOpt,
<B as Extensible>::Opts: Send,
<B as Extensible>::Opts: Sync,
An initialization routine. Read more
Performs the conversion.
Performs the conversion.
type UninstallHandle = Either<A::UninstallHandle, B::UninstallHandle>
type UninstallHandle = Either<A::UninstallHandle, B::UninstallHandle>
A handle representing lifetime of the resource. Read more
Installs another instance of the resource. Read more
This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
This method tests greater than (for self
and other
) and is used by the >
operator. Read more
Attempt to pull out the next value of this stream, registering the
current task for wakeup if the value is not yet available, and returning
None
if the stream is exhausted. Read more
Returns the documentation for the type. Read more
Auto Trait Implementations
impl<A, B> RefUnwindSafe for Either<A, B> where
A: RefUnwindSafe,
B: RefUnwindSafe,
impl<A, B> UnwindSafe for Either<A, B> where
A: UnwindSafe,
B: UnwindSafe,
Blanket Implementations
Reads all bytes into buf
until the delimiter byte
or EOF is reached. Read more
Reads all bytes until a newline (the 0xA byte) is reached, and append them to the provided buffer. Read more
Returns a stream of the contents of this reader split on the byte
byte
. Read more
Returns the contents of the internal buffer, filling it with more data from the inner reader if it is empty. Read more
Returns a stream over the lines of this reader.
This method is the async equivalent to BufRead::lines
. Read more
Creates a new AsyncRead
instance that chains this stream with
next
. Read more
Pulls some bytes from this source into the specified buffer, returning how many bytes were read. Read more
Pulls some bytes from this source into the specified buffer, advancing the buffer’s internal cursor. Read more
Reads the exact number of bytes required to fill buf
. Read more
Reads an unsigned 8 bit integer from the underlying reader. Read more
Reads a signed 8 bit integer from the underlying reader. Read more
Reads an unsigned 16-bit integer in big-endian order from the underlying reader. Read more
Reads a signed 16-bit integer in big-endian order from the underlying reader. Read more
Reads an unsigned 32-bit integer in big-endian order from the underlying reader. Read more
Reads a signed 32-bit integer in big-endian order from the underlying reader. Read more
Reads an unsigned 64-bit integer in big-endian order from the underlying reader. Read more
Reads an signed 64-bit integer in big-endian order from the underlying reader. Read more
Reads an unsigned 128-bit integer in big-endian order from the underlying reader. Read more
Reads an signed 128-bit integer in big-endian order from the underlying reader. Read more
Reads an 32-bit floating point type in big-endian order from the underlying reader. Read more
Reads an 64-bit floating point type in big-endian order from the underlying reader. Read more
Reads an unsigned 16-bit integer in little-endian order from the underlying reader. Read more
Reads a signed 16-bit integer in little-endian order from the underlying reader. Read more
Reads an unsigned 32-bit integer in little-endian order from the underlying reader. Read more
Reads a signed 32-bit integer in little-endian order from the underlying reader. Read more
Reads an unsigned 64-bit integer in little-endian order from the underlying reader. Read more
Reads an signed 64-bit integer in little-endian order from the underlying reader. Read more
Reads an unsigned 128-bit integer in little-endian order from the underlying reader. Read more
Reads an signed 128-bit integer in little-endian order from the underlying reader. Read more
Reads an 32-bit floating point type in little-endian order from the underlying reader. Read more
Reads an 64-bit floating point type in little-endian order from the underlying reader. Read more
Reads all bytes until EOF in this source, placing them into buf
. Read more
fn read_to_string(&'a mut self, dst: &'a mut String) -> ReadToString<'a, Self> where
Self: Unpin,
fn read_to_string(&'a mut self, dst: &'a mut String) -> ReadToString<'a, Self> where
Self: Unpin,
Reads all bytes until EOF in this source, appending them to buf
. Read more
Creates a future which will seek an IO object, and then yield the new position in the object and the object itself. Read more
Creates a future which will rewind to the beginning of the stream. Read more
Creates a future which will return the current seek position from the start of the stream. Read more
Writes a buffer into this writer, returning how many bytes were written. Read more
Writes a buffer into this writer, advancing the buffer’s internal cursor. Read more
fn write_all_buf<B>(&'a mut self, src: &'a mut B) -> WriteAllBuf<'a, Self, B> where
Self: Unpin,
B: Buf,
fn write_all_buf<B>(&'a mut self, src: &'a mut B) -> WriteAllBuf<'a, Self, B> where
Self: Unpin,
B: Buf,
Attempts to write an entire buffer into this writer Read more
Attempts to write an entire buffer into this writer. Read more
Writes an unsigned 8-bit integer to the underlying writer. Read more
Writes an unsigned 8-bit integer to the underlying writer. Read more
Writes an unsigned 16-bit integer in big-endian order to the underlying writer. Read more
Writes a signed 16-bit integer in big-endian order to the underlying writer. Read more
Writes an unsigned 32-bit integer in big-endian order to the underlying writer. Read more
Writes a signed 32-bit integer in big-endian order to the underlying writer. Read more
Writes an unsigned 64-bit integer in big-endian order to the underlying writer. Read more
Writes an signed 64-bit integer in big-endian order to the underlying writer. Read more
Writes an unsigned 128-bit integer in big-endian order to the underlying writer. Read more
Writes an signed 128-bit integer in big-endian order to the underlying writer. Read more
Writes an 32-bit floating point type in big-endian order to the underlying writer. Read more
Writes an 64-bit floating point type in big-endian order to the underlying writer. Read more
Writes an unsigned 16-bit integer in little-endian order to the underlying writer. Read more
Writes a signed 16-bit integer in little-endian order to the underlying writer. Read more
Writes an unsigned 32-bit integer in little-endian order to the underlying writer. Read more
Writes a signed 32-bit integer in little-endian order to the underlying writer. Read more
Writes an unsigned 64-bit integer in little-endian order to the underlying writer. Read more
Writes an signed 64-bit integer in little-endian order to the underlying writer. Read more
Writes an unsigned 128-bit integer in little-endian order to the underlying writer. Read more
Writes an signed 128-bit integer in little-endian order to the underlying writer. Read more
Writes an 32-bit floating point type in little-endian order to the underlying writer. Read more
Writes an 64-bit floating point type in little-endian order to the underlying writer. Read more
Flushes this output stream, ensuring that all intermediately buffered contents reach their destination. Read more
Mutably borrows from an owned value. Read more
Map this future’s output to a different type, returning a new future of the resulting type. Read more
Map this future’s output to a different type, returning a new future of the resulting type. Read more
Chain on a computation for when a future finished, passing the result of
the future to the provided closure f
. Read more
Wrap this future in an Either
future, making it the left-hand variant
of that Either
. Read more
Wrap this future in an Either
future, making it the right-hand variant
of that Either
. Read more
Convert this future into a single element stream. Read more
Flatten the execution of this future when the output of this future is itself another future. Read more
Flatten the execution of this future when the successful result of this future is a stream. Read more
Fuse a future such that poll
will never again be called once it has
completed. This method can be used to turn any Future
into a
FusedFuture
. Read more
Do something with the output of a future before passing it on. Read more
Turns a Future<Output = T>
into a
TryFuture<Ok = T, Error = ()
>. Read more
Turns a Future<Output = T>
into a
TryFuture<Ok = T, Error = Never
>. Read more
A convenience for calling Future::poll
on Unpin
future types.
Evaluates and consumes the future, returning the resulting output if
the future is ready after the first call to Future::poll
. Read more
into_future
)The output that the future will produce on completion.
type Future = F
type Future = F
into_future
)Which kind of future are we turning this into?
into_future
)Creates a future from a value.
Creates a future that resolves to the next item in the stream. Read more
Maps this stream’s items to a different type, returning a new stream of the resulting type. Read more
Creates a stream which gives the current iteration count as well as the next value. Read more
Filters the values produced by this stream according to the provided asynchronous predicate. Read more
Filters the values produced by this stream while simultaneously mapping them to a different type according to the provided asynchronous closure. Read more
Computes from this stream’s items new items of a different type using an asynchronous closure. Read more
Transforms a stream into a collection, returning a future representing the result of that computation. Read more
Converts a stream of pairs into a future, which resolves to pair of containers. Read more
fn concat(self) -> Concat<Self> where
Self::Item: Extend<<Self::Item as IntoIterator>::Item>,
Self::Item: IntoIterator,
Self::Item: Default,
fn concat(self) -> Concat<Self> where
Self::Item: Extend<<Self::Item as IntoIterator>::Item>,
Self::Item: IntoIterator,
Self::Item: Default,
Concatenate all items of a stream into a single extendable destination, returning a future representing the end result. Read more
Execute an accumulating asynchronous computation over a stream, collecting all the values into one final result. Read more
Execute predicate over asynchronous stream, and return true
if any element in stream satisfied a predicate. Read more
Execute predicate over asynchronous stream, and return true
if all element in stream satisfied a predicate. Read more
Flattens a stream of streams into just one continuous stream. Read more
Maps a stream like StreamExt::map
but flattens nested Stream
s. Read more
Combinator similar to StreamExt::fold
that holds internal state
and produces a new stream. Read more
Skip elements on this stream while the provided asynchronous predicate
resolves to true
. Read more
Take elements from this stream while the provided asynchronous predicate
resolves to true
. Read more
Take elements from this stream until the provided future resolves. Read more
Runs this stream to completion, executing the provided asynchronous closure for each element on the stream. Read more
Creates a new stream of at most n
items of the underlying stream. Read more
Creates a new stream which skips n
items of the underlying stream. Read more
An adapter for zipping two streams together. Read more
Adapter for chaining two streams. Read more
Do something with each item of this stream, afterwards passing it on. Read more
Wrap this stream in an Either
stream, making it the left-hand variant
of that Either
. Read more
Wrap this stream in an Either
stream, making it the right-hand variant
of that Either
. Read more
Consumes and returns the next value in the stream or None
if the
stream is finished. Read more
Consumes and returns the next item in the stream. If an error is encountered before the next item, the error is returned instead. Read more
Maps this stream’s items to a different type, returning a new stream of the resulting type. Read more
Combine two streams into one by interleaving the output of both as it is produced. Read more
Filters the values produced by this stream according to the provided predicate. Read more
Filters the values produced by this stream while simultaneously mapping them to a different type according to the provided closure. Read more
Creates a new stream of at most n
items of the underlying stream. Read more
Take elements from this stream while the provided predicate
resolves to true
. Read more
Creates a new stream that will skip the n
first items of the
underlying stream. Read more
Skip elements from the underlying stream while the provided predicate
resolves to true
. Read more
Tests if every element of the stream matches a predicate. Read more
Tests if any element of the stream matches a predicate. Read more
Combine two streams into one by first returning all values from the first stream then all values from the second stream. Read more
A combinator that applies a function to every element in a stream producing a single, final value. Read more
Drain stream pushing all emitted values into a collection. Read more
Applies a per-item timeout to the passed stream. Read more