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 Fragments 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 Fragments with simple enough Drivers (drivers that don’t sub-divide their Fragments). 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

A(A)

Tuple Fields of A

0: A
B(B)

Tuple Fields of B

0: B

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

The type of the accepted connection.

Poll for availability of the next connection. Read more

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

Tells this buffer that amt bytes have been consumed from the buffer, so they should no longer be returned in calls to poll_read. Read more

Attempts to read from the AsyncRead into buf. Read more

Attempts to seek to an offset, in bytes, in a stream. Read more

Waits for a seek operation to complete. 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

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Compares two fragments.

Formats the value using the given formatter. Read more

Deserialize this value from the given Serde deserializer. Read more

The smaller Fragment the driver cuts F into. Read more

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

Informs if there’s a chance the new fragment will use something in the Driver’s cache if applied. Read more

The default driver to be used by the fragment. Read more

The default installer to be used unless a transformation or the user doesn’t provide one. Read more

The intermediate product if the fragment supports two-stage creation of Resources. If not, it can be set to (). Read more

The actual product this Fragment creates.

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

An initialization routine. Read more

Performs the conversion.

Performs the conversion.

Performs the conversion.

Performs the conversion.

The type of value produced on completion.

Attempt to resolve the future to a final value, registering the current task for wakeup if the value is not yet available. Read more

Feeds this value into the given Hasher. Read more

Feeds a slice of this type into the given Hasher. Read more

A handle representing lifetime of the resource. Read more

Installs another instance of the resource. Read more

Initialize the installer. Read more

This method returns an Ordering between self and other. Read more

Compares and returns the maximum of two values. Read more

Compares and returns the minimum of two values. Read more

Restrict a value to a certain interval. Read more

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

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

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more

Serialize this value into the given Serde serializer. Read more

Values yielded by the stream.

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 bounds on the remaining length of the stream. Read more

Returns the documentation for the type. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

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

Tells this buffer that amt bytes have been consumed from the buffer, so they should no longer be returned in calls to read. 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

Reads all bytes until EOF in this source, appending them to buf. Read more

Creates an adaptor which reads at most limit bytes from it. 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

Like write, except that it writes from a slice of buffers. Read more

Writes a buffer into this writer, advancing the buffer’s internal cursor. Read more

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

Shuts down the output stream, ensuring that the value can be dropped cleanly. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

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

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

Performs the conversion.

🔬 This is a nightly-only experimental API. (into_future)

The output that the future will produce on completion.

🔬 This is a nightly-only experimental API. (into_future)

Which kind of future are we turning this into?

🔬 This is a nightly-only experimental API. (into_future)

Creates a future from a value.

Turns self into the result.

Creates a future that resolves to the next item in the stream. Read more

Converts this stream into a future of (next_item, tail_of_stream). If the stream terminates, then the next item is None. 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

Concatenate all items of a stream into a single extendable destination, returning a future representing the end result. Read more

Repeats a stream endlessly. 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 Streams. 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

Fuse a stream such that poll_next will never again be called once it has finished. This method can be used to turn any Stream into a FusedStream. Read more

Borrows a stream, rather than consuming it. Read more

An adapter for zipping two streams together. Read more

Adapter for chaining two streams. Read more

Creates a new stream which exposes a peek method. 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

A convenience method for calling [Stream::poll_next] on Unpin stream types. Read more

Returns a Future that resolves when the next item in this stream is ready. 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 stream which ends after the first None. 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

Slows down a stream by enforcing a delay between items. Read more

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

recently added

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.