pub enum Either<A, B> {
A(A),
B(B),
}
Expand description
Combines two different responder types into a single type
use actix_web::{AsyncResponder, Either, Error, HttpRequest, HttpResponse};
use futures::future::result;
type RegisterResult =
Either<HttpResponse, Box<Future<Item = HttpResponse, Error = Error>>>;
fn index(req: HttpRequest) -> RegisterResult {
if is_a_variant() {
// <- choose variant A
Either::A(HttpResponse::BadRequest().body("Bad data"))
} else {
Either::B(
// <- variant B
result(Ok(HttpResponse::Ok()
.content_type("text/html")
.body("Hello!")))
.responder(),
)
}
}
Variants
A(A)
First branch of the type
B(B)
Second branch of the type
Trait Implementations
sourceimpl<A: 'static, B: 'static, S: 'static> FromRequest<S> for Either<A, B>where
A: FromRequest<S>,
B: FromRequest<S>,
impl<A: 'static, B: 'static, S: 'static> FromRequest<S> for Either<A, B>where
A: FromRequest<S>,
B: FromRequest<S>,
Extract either one of two fields from the request.
If both or none of the fields can be extracted, the default behaviour is to prefer the first
successful, last that failed. The behaviour can be changed by setting the appropriate
EitherCollisionStrategy
.
CAVEAT: Most of the time both extractors will be run. Make sure that the extractors you specify
can be run one after another (or in parallel). This will always fail for extractors that modify
the request state (such as the Form
extractors that read in the body stream).
So Either<Form, Form> will not work correctly - it will only succeed if it matches the first
option, but will always fail to match the second (since the body stream will be at the end, and
appear to be empty).
Example
extern crate rand;
#[macro_use] extern crate serde_derive;
use actix_web::{http, App, Result, HttpRequest, Error, FromRequest};
use actix_web::error::ErrorBadRequest;
use actix_web::Either;
#[derive(Debug, Deserialize)]
struct Thing { name: String }
#[derive(Debug, Deserialize)]
struct OtherThing { id: String }
impl<S> FromRequest<S> for Thing {
type Config = ();
type Result = Result<Thing, Error>;
#[inline]
fn from_request(req: &HttpRequest<S>, _cfg: &Self::Config) -> Self::Result {
if rand::random() {
Ok(Thing { name: "thingy".into() })
} else {
Err(ErrorBadRequest("no luck"))
}
}
}
impl<S> FromRequest<S> for OtherThing {
type Config = ();
type Result = Result<OtherThing, Error>;
#[inline]
fn from_request(req: &HttpRequest<S>, _cfg: &Self::Config) -> Self::Result {
if rand::random() {
Ok(OtherThing { id: "otherthingy".into() })
} else {
Err(ErrorBadRequest("no luck"))
}
}
}
/// extract text data from request
fn index(supplied_thing: Either<Thing, OtherThing>) -> Result<String> {
match supplied_thing {
Either::A(thing) => Ok(format!("Got something: {:?}", thing)),
Either::B(other_thing) => Ok(format!("Got anotherthing: {:?}", other_thing))
}
}
fn main() {
let app = App::new().resource("/users/:first", |r| {
r.method(http::Method::POST).with(index)
});
}
type Config = EitherConfig<A, B, S>
type Config = EitherConfig<A, B, S>
type Result = AsyncResult<Either<A, B>, Error>
type Result = AsyncResult<Either<A, B>, Error>
sourcefn from_request(req: &HttpRequest<S>, cfg: &Self::Config) -> Self::Result
fn from_request(req: &HttpRequest<S>, cfg: &Self::Config) -> Self::Result
sourcefn extract(req: &HttpRequest<S>) -> Self::Result
fn extract(req: &HttpRequest<S>) -> Self::Result
sourceimpl<A, B, I, E> Future for Either<A, B>where
A: Future<Item = I, Error = E>,
B: Future<Item = I, Error = E>,
impl<A, B, I, E> Future for Either<A, B>where
A: Future<Item = I, Error = E>,
B: Future<Item = I, Error = E>,
type Error = E
type Error = E
sourcefn poll(&mut self) -> Poll<I, E>
fn poll(&mut self) -> Poll<I, E>
sourcefn wait(self) -> Result<Self::Item, Self::Error>where
Self: Sized,
fn wait(self) -> Result<Self::Item, Self::Error>where
Self: Sized,
sourcefn map<F, U>(self, f: F) -> Map<Self, F>where
F: FnOnce(Self::Item) -> U,
Self: Sized,
fn map<F, U>(self, f: F) -> Map<Self, F>where
F: FnOnce(Self::Item) -> U,
Self: Sized,
sourcefn map_err<F, E>(self, f: F) -> MapErr<Self, F>where
F: FnOnce(Self::Error) -> E,
Self: Sized,
fn map_err<F, E>(self, f: F) -> MapErr<Self, F>where
F: FnOnce(Self::Error) -> E,
Self: Sized,
sourcefn from_err<E>(self) -> FromErr<Self, E>where
E: From<Self::Error>,
Self: Sized,
fn from_err<E>(self) -> FromErr<Self, E>where
E: From<Self::Error>,
Self: Sized,
From
for
this future’s Error
, returning a new future. Read moresourcefn then<F, B>(self, f: F) -> Then<Self, B, F>where
F: FnOnce(Result<Self::Item, Self::Error>) -> B,
B: IntoFuture,
Self: Sized,
fn then<F, B>(self, f: F) -> Then<Self, B, F>where
F: FnOnce(Result<Self::Item, Self::Error>) -> B,
B: IntoFuture,
Self: Sized,
f
. Read moresourcefn and_then<F, B>(self, f: F) -> AndThen<Self, B, F>where
F: FnOnce(Self::Item) -> B,
B: IntoFuture<Error = Self::Error>,
Self: Sized,
fn and_then<F, B>(self, f: F) -> AndThen<Self, B, F>where
F: FnOnce(Self::Item) -> B,
B: IntoFuture<Error = Self::Error>,
Self: Sized,
sourcefn or_else<F, B>(self, f: F) -> OrElse<Self, B, F>where
F: FnOnce(Self::Error) -> B,
B: IntoFuture<Item = Self::Item>,
Self: Sized,
fn or_else<F, B>(self, f: F) -> OrElse<Self, B, F>where
F: FnOnce(Self::Error) -> B,
B: IntoFuture<Item = Self::Item>,
Self: Sized,
sourcefn select<B>(self, other: B) -> Select<Self, <B as IntoFuture>::Future>where
B: IntoFuture<Item = Self::Item, Error = Self::Error>,
Self: Sized,
fn select<B>(self, other: B) -> Select<Self, <B as IntoFuture>::Future>where
B: IntoFuture<Item = Self::Item, Error = Self::Error>,
Self: Sized,
sourcefn select2<B>(self, other: B) -> Select2<Self, <B as IntoFuture>::Future>where
B: IntoFuture,
Self: Sized,
fn select2<B>(self, other: B) -> Select2<Self, <B as IntoFuture>::Future>where
B: IntoFuture,
Self: Sized,
sourcefn join<B>(self, other: B) -> Join<Self, <B as IntoFuture>::Future>where
B: IntoFuture<Error = Self::Error>,
Self: Sized,
fn join<B>(self, other: B) -> Join<Self, <B as IntoFuture>::Future>where
B: IntoFuture<Error = Self::Error>,
Self: Sized,
sourcefn join3<B, C>(
self,
b: B,
c: C
) -> Join3<Self, <B as IntoFuture>::Future, <C as IntoFuture>::Future>where
B: IntoFuture<Error = Self::Error>,
C: IntoFuture<Error = Self::Error>,
Self: Sized,
fn join3<B, C>(
self,
b: B,
c: C
) -> Join3<Self, <B as IntoFuture>::Future, <C as IntoFuture>::Future>where
B: IntoFuture<Error = Self::Error>,
C: IntoFuture<Error = Self::Error>,
Self: Sized,
join
, but with more futures.sourcefn join4<B, C, D>(
self,
b: B,
c: C,
d: D
) -> Join4<Self, <B as IntoFuture>::Future, <C as IntoFuture>::Future, <D as IntoFuture>::Future>where
B: IntoFuture<Error = Self::Error>,
C: IntoFuture<Error = Self::Error>,
D: IntoFuture<Error = Self::Error>,
Self: Sized,
fn join4<B, C, D>(
self,
b: B,
c: C,
d: D
) -> Join4<Self, <B as IntoFuture>::Future, <C as IntoFuture>::Future, <D as IntoFuture>::Future>where
B: IntoFuture<Error = Self::Error>,
C: IntoFuture<Error = Self::Error>,
D: IntoFuture<Error = Self::Error>,
Self: Sized,
join
, but with more futures.sourcefn join5<B, C, D, E>(
self,
b: B,
c: C,
d: D,
e: E
) -> Join5<Self, <B as IntoFuture>::Future, <C as IntoFuture>::Future, <D as IntoFuture>::Future, <E as IntoFuture>::Future>where
B: IntoFuture<Error = Self::Error>,
C: IntoFuture<Error = Self::Error>,
D: IntoFuture<Error = Self::Error>,
E: IntoFuture<Error = Self::Error>,
Self: Sized,
fn join5<B, C, D, E>(
self,
b: B,
c: C,
d: D,
e: E
) -> Join5<Self, <B as IntoFuture>::Future, <C as IntoFuture>::Future, <D as IntoFuture>::Future, <E as IntoFuture>::Future>where
B: IntoFuture<Error = Self::Error>,
C: IntoFuture<Error = Self::Error>,
D: IntoFuture<Error = Self::Error>,
E: IntoFuture<Error = Self::Error>,
Self: Sized,
join
, but with more futures.sourcefn into_stream(self) -> IntoStream<Self>where
Self: Sized,
fn into_stream(self) -> IntoStream<Self>where
Self: Sized,
sourcefn fuse(self) -> Fuse<Self>where
Self: Sized,
fn fuse(self) -> Fuse<Self>where
Self: Sized,
poll
will never again be called once it has
completed. Read moresourcefn inspect<F>(self, f: F) -> Inspect<Self, F>where
F: FnOnce(&Self::Item),
Self: Sized,
fn inspect<F>(self, f: F) -> Inspect<Self, F>where
F: FnOnce(&Self::Item),
Self: Sized,
sourceimpl<A: PartialEq, B: PartialEq> PartialEq<Either<A, B>> for Either<A, B>
impl<A: PartialEq, B: PartialEq> PartialEq<Either<A, B>> for Either<A, B>
sourceimpl<A, B> Responder for Either<A, B>where
A: Responder,
B: Responder,
impl<A, B> Responder for Either<A, B>where
A: Responder,
B: Responder,
type Item = AsyncResult<HttpResponse, Error>
type Item = AsyncResult<HttpResponse, Error>
sourcefn respond_to<S: 'static>(
self,
req: &HttpRequest<S>
) -> Result<AsyncResult<HttpResponse>, Error>
fn respond_to<S: 'static>(
self,
req: &HttpRequest<S>
) -> Result<AsyncResult<HttpResponse>, Error>
AsyncResult
or Error
.