[−][src]Struct hyperbole::Ctx
A request processing context.
It can be thought of as a composable chain of partial transformations over an hlist of request scoped values; a lazily declarative specification of 'how to process a request'.
Much like Iterator, a context by itself doesn't really do anything (it is dropped by the time requests are being processed). It exists only to construct request handlers for registration as routes in an App.
Each context tracks three hlists and a combinator chain that transforms them:
- An hlist provided at App initialization time (via
App::new
orApp::empty
). - An hlist generated from incoming http request parts.
- An hlist of parameters parsed from request uris.
See Init for the exact set of initial state available in fresh contexts.
When a request is matched, these are all merged and fed into the chain of combinators to be transformed before being passed into an eventual handler.
Combinators may move arbitrary subsets of the context's request scoped state, and return arbitrary sets of state to merge for later combinators to use. In this way, the data dependencies between middlewares / handlers can be expressed at compile time, without introducing unnecessary coupling between components that are logically unrelated.
use hyper::Body; use hyperbole::{hlist, App, Hlist}; #[derive(Copy, Clone)] struct DbHandle; struct A; struct B; let _ctx = App::new(hlist![DbHandle]) // top-level state can be injected here .context() // move nothing, and return nothing to be merged .map(|cx: Hlist![]| cx) // move req body, but merge it back .map(|cx: Hlist![Body]| cx) // move req body, and merge an A and B .map(|cx: Hlist![Body]| hlist![A, B]) // subset ordering doesn't matter .map(|cx: Hlist![B, DbHandle, A]| cx) .then(|cx: Hlist![A]| async { cx }) .map(|cx: Hlist![A, B]| cx) .then(|cx: Hlist![B]| async { cx });
At any point in a context chain, a handler can be registered by calling handle or one of its analogues (ex: get, post). Like middleware combinators, handlers move a subset of the request scoped state into themselves, but instead of returning more state to merge they return a value that implements Reply.
use hyper::Body; use hyperbole::{access, path, record, record_args, App, Hlist}; let _ctx = App::empty() .context_path(path![dynamic: u32]) // GET /:dynamic/echo_req .get(path!["echo_req"], |cx: Hlist![Body]| async move { // hlists can be converted into tuples let (body,) = cx.into(); format!("echo: {:?}", body) }) // GET /:dynamic/tell_dynamic .get(path!["tell_dynamic"], |cx: record![dynamic]| async move { // or use the access! macro for named field accesses format!("dynamic is {}", access!(&cx.dynamic)) }) .path(path!["all" / "the" / "subpaths"]) // GET /:dynamic/all/the/subpaths/discrete .get(path!["discrete"], fn_handler); // or use the record_args attribute to reduce boilerplate #[record_args] async fn fn_handler(dynamic: u32, _body: Body) -> &'static [u8] { println!("dynamic: {}", dynamic); println!("reqbody: {:?}", _body); b"here's an octet-stream" }
Error Handling
Errors that arise during request resolution are represented in the context as coproducts (a generalization of enums). When a fallible middleware is used (try_map or try_then), an additional error variant is added to the context's error coproduct. This also applies to parse errors of dynamic path parameters (which are wrapped in a tree::UriError).
If a fallible middleware returns Err
, the request being processed short circuits and cannot
be recovered. The specific error response returned to the client can however be modified by
map_errs or map_err. The former transforms the complete error coproduct, while the latter
maps over a single variant.
Much like with request scoped state, any referenced errors in a map_errs or map_err must appear in some fallible combinator. This is enforced at compile time.
use hyper::StatusCode; use hyperbole::{ body::{jsonr, JsonBodyError}, record, reply::Reply, App, Coprod, }; let _app = App::empty() .context() // attempt to parse the body as a json object: .try_then(jsonr::<record![x: u32, y: String]>) // if the above fails, we can adjust the error with map_err: .map_err(|err: JsonBodyError| err) // or we can adjust all possible errors with map_errs: .map_errs(|errs| { let code = StatusCode::INTERNAL_SERVER_ERROR; let err = format!("{:?}", errs).with_status(code); // return type must be a coproduct as well <Coprod![_]>::inject(err) }) .collapse();
Limitations
Due to the extensive use of type inference to extract subsets of the request scoped state, the state may not contain duplicate instances of a type. That is, it is a set, and not a list. This property arises without explicit enforcement; type inference will simply begin failing if duplicate types are encountered.
use hyperbole::{hlist, App, Hlist}; struct A(u32); let _app = App::empty() .context() // merge an A .map(|cx: Hlist![]| hlist![A(1)]) // merge an A (state now contains two `A`s) .map(|cx: Hlist![]| hlist![A(2)]) // this fails during type inference, because it's ambiguous _which_ A we want // // error[E0282]: type annotations needed // cannot infer type for type parameter `TailIndex` .map(|cx: Hlist![A]| cx) .collapse();
Named fields can be used to disambiguate between what would otherwise be
duplicate types. path! in particular takes advantage of this to allow multiple instances
of common primitive types like u32
or String
to be extracted from a uri.
The above example can be rewritten using named fields to avoid the inference failure:
use hyperbole::{record, App}; struct A(u32); let _app = App::empty() .context() .map(|cx: record![]| record![first = A(1)]) .map(|cx: record![]| record![second = A(2)]) // we want the A called 'second' .map(|cx: record![second]| cx) // we want the A called 'first' .map(|cx: record![first]| cx) // we want both of them .map(|cx: record![first, second]| cx) .collapse();
Implementations
impl<I: 'static, P: 'static, L: 'static> Ctx<I, P, L> where
I: Sync + Send + Clone,
L: Sync + Send + Clone,
[src]
I: Sync + Send + Clone,
L: Sync + Send + Clone,
pub fn inject<T: Clone>(self, value: T) -> Ctx<I, P, Inject<L, T>> where
Inject<L, T>: Link<Init<I>, P>,
[src]
Inject<L, T>: Link<Init<I>, P>,
Inject a cloneable value into the request scoped state.
Examples
use hyperbole::{f, hlist, record, App, Hlist}; let _ctx = App::empty() .context() .inject("just an &str") .map(|cx: Hlist![&str]| hlist![]) .inject(f![xyz = "this is a named field"]) .map(|cx: record![xyz]| hlist![]);
pub fn map<F, Args, Ix, Merge>(self, f: F) -> Ctx<I, P, Map<L, F, Args, Ix>> where
F: Fn(Args) -> Merge,
Merge: HList,
Map<L, F, Args, Ix>: Link<Init<I>, P>,
[src]
F: Fn(Args) -> Merge,
Merge: HList,
Map<L, F, Args, Ix>: Link<Init<I>, P>,
Transform a subset of the request scoped state with a closure.
The provided closure should accept an hlist argument, and return an hlist.
The argument hlist may consist of any subset of types that are present within the
context's state up to this point. Each element will be removed from the context's
state and moved into f
upon execution (making them inaccessible to subsequent
middlewares and handlers).
Likewise, any types in the returned hlist will be moved into the context's state.
Examples
use hyper::Body; use hyperbole::{hlist, record_args, App, Hlist}; #[record_args] fn fun(_: Body, _: u32) -> Hlist![] { hlist![] } let _ctx = App::empty() .context() .map(|cx: Hlist![Body]| cx) .map(|cx: Hlist![]| hlist![12345]) .map(fun);
pub fn try_map<F, Args, Ix, Merge, E>(
self,
f: F
) -> Ctx<I, P, TryMap<L, F, Args, Ix>> where
F: Fn(Args) -> Result<Merge, E>,
Merge: HList,
E: Reply,
TryMap<L, F, Args, Ix>: Link<Init<I>, P>,
[src]
self,
f: F
) -> Ctx<I, P, TryMap<L, F, Args, Ix>> where
F: Fn(Args) -> Result<Merge, E>,
Merge: HList,
E: Reply,
TryMap<L, F, Args, Ix>: Link<Init<I>, P>,
Transform a subset of the request scoped state with a fallible closure.
The provided closure should accept an hlist argument, and return an hlist in a Result (where the error type implements Reply).
The argument hlist may consist of any subset of types that are present within the
context's state up to this point. Each element will be removed from the context's
state and moved into f
upon execution (making them inaccessible to subsequent
middlewares and handlers).
If the closure returns Ok
, any types in the returned hlist will be moved into the
context's state.
If the closure returns Err
, the request will short circuit with a response created
via the error's Reply implementation.
For subsequent combinators, the context's error type will contain an additional variant
for E
.
Examples
use hyperbole::{access, path, record, App}; let _ctx = App::empty() .context_path(path![a: u32 / b: u32]) .try_map(|cx: record![a, b]| match access!(&cx.a) > access!(&cx.b) { false => Err("uh oh"), true => Ok(cx), }) .map_err(|e: &str| "e is the above error, if it happened");
pub fn then<F, Args, Ix, Fut, Merge>(
self,
f: F
) -> Ctx<I, P, Then<L, F, Args, Ix>> where
F: Fn(Args) -> Fut,
Fut: Future<Output = Merge>,
Merge: HList,
Then<L, F, Args, Ix>: Link<Init<I>, P>,
[src]
self,
f: F
) -> Ctx<I, P, Then<L, F, Args, Ix>> where
F: Fn(Args) -> Fut,
Fut: Future<Output = Merge>,
Merge: HList,
Then<L, F, Args, Ix>: Link<Init<I>, P>,
Transform a subset of the request scoped state with a closure that returns a future.
The provided closure should accept an hlist argument, and return a future that evaluates to an hlist.
The argument hlist may consist of any subset of types that are present within the
context's state up to this point. Each element will be removed from the context's
state and moved into f
upon execution (making them inaccessible to subsequent
middlewares and handlers).
Likewise, any types in the returned hlist will be moved into the context's state.
Examples
use hyper::Body; use hyperbole::{hlist, record_args, App, Hlist}; #[record_args] async fn fun(_: Body) -> Hlist![] { hlist![] } let _ctx = App::empty() .context() .then(|cx: Hlist![Body]| async move { cx }) .then(|cx: Hlist![]| async move { cx }) .then(fun);
pub fn try_then<F, Args, Ix, Fut, Merge, E>(
self,
f: F
) -> Ctx<I, P, TryThen<L, F, Args, Ix>> where
F: Fn(Args) -> Fut,
Fut: Future<Output = Result<Merge, E>>,
Merge: HList,
E: Reply,
TryThen<L, F, Args, Ix>: Link<Init<I>, P>,
[src]
self,
f: F
) -> Ctx<I, P, TryThen<L, F, Args, Ix>> where
F: Fn(Args) -> Fut,
Fut: Future<Output = Result<Merge, E>>,
Merge: HList,
E: Reply,
TryThen<L, F, Args, Ix>: Link<Init<I>, P>,
Transform a subset of the request scoped state with a closure that returns a fallible future.
The provided closure should accept an hlist argument, and return a future that evaluates to an hlist in a Result (where the error type implements Reply).
The argument hlist may consist of any subset of types that are present within the
context's state up to this point. Each element will be removed from the context's
state and moved into f
upon execution (making them inaccessible to subsequent
middlewares and handlers).
If the future evaluates to Ok
, any types in the returned hlist will be moved into
the context's state.
If the future evaluates to Err
, the request will short circuit with a response created
via the error's Reply implementation.
For subsequent combinators, the context's error type will contain an additional variant
for E
.
Examples
use hyperbole::{path, record, App}; let _ctx = App::empty() .context_path(path![a: f64 / b: String]) .try_then(|cx: record![a, b]| async move { let (a, b) = cx.into(); if *a == 3.14159265 && *b != "blue" { Err("always blue!") } else { Ok(record![color = "it was blue!"]) } }) .map(|cx: record![color]| cx);
pub fn map_errs<F, E>(self, f: F) -> Ctx<I, P, MapErrs<L, F>> where
F: Fn(<L as Link<Init<I>, P>>::Error) -> E,
E: IsCoproduct + Reply,
L: Link<Init<I>, P>,
MapErrs<L, F>: Link<Init<I>, P>,
[src]
F: Fn(<L as Link<Init<I>, P>>::Error) -> E,
E: IsCoproduct + Reply,
L: Link<Init<I>, P>,
MapErrs<L, F>: Link<Init<I>, P>,
Transform the context's error type with a closure.
The error will be a Coproduct with a variant for all potential error cases so far.
Any Coproduct may be returned, so long as any variants it contains all implement Reply.
Examples
use hyperbole::{record, App, Coprod}; let _ctx = App::empty() .context() // without any fallible combinators, the error is an uninhabitable enum: .map_errs(|err: Coprod![]| -> Coprod![] { match err {} }) .map(|cx: record![]| cx) .collapse();
pub fn map_err<F, E, Ix, R>(self, f: F) -> Ctx<I, P, MapErr<L, F, E, Ix>> where
F: Fn(E) -> R,
R: Reply,
MapErr<L, F, E, Ix>: Link<Init<I>, P>,
[src]
F: Fn(E) -> R,
R: Reply,
MapErr<L, F, E, Ix>: Link<Init<I>, P>,
Transform a single variant of the context's error type with a closure.
This can be used to selectively modify only a single type of error. Note that if more than one instance of the same error type may have occurred, this will only affect the most recent of them.
Examples
use hyperbole::{record, record_args, App}; fn fallible_a(_: record![]) -> Result<record![], String> { Err("uh oh".to_owned()) } #[record_args] fn fallible_b() -> Result<record![], Vec<u8>> { Err(b"uh oh".to_vec()) } let _app = App::empty() .context() .try_map(fallible_a) .try_map(fallible_b) .map_err(|e: String| "it was String") .map_err(|e: Vec<u8>| "it was Vec<u8>") .collapse();
pub fn path<_P, Ix>(
self,
spec: PathSpec<_P>
) -> Ctx<I, <P as Add<Params<_P>>>::Output, Path<L, _P, Ix>> where
P: Add<Params<_P>>,
_P: Parser<Segment>,
Path<L, _P, Ix>: Link<Init<I>, <P as Add<Params<_P>>>::Output>,
[src]
self,
spec: PathSpec<_P>
) -> Ctx<I, <P as Add<Params<_P>>>::Output, Path<L, _P, Ix>> where
P: Add<Params<_P>>,
_P: Parser<Segment>,
Path<L, _P, Ix>: Link<Init<I>, <P as Add<Params<_P>>>::Output>,
Append additional path segments to this context's base path. Any new parameters parsed from the uri will be merged into the context's state at this point.
The path! macro can be used to construct an appropriate PathSpec
.
When a request is being handled, the concatenated path specification is parsed before any middlewares execute. However, all extracted parameters (and parsing errors) are deferred such that they only appear at the point where they were specified.
Examples
use hyperbole::{path, record, tree::UriError, App}; use std::num::ParseFloatError; let _ctx = App::empty() .context() .path(path!["first" / x: usize / y: f64]) .map(|cx: record![x]| cx) .map_err(|e: UriError<ParseFloatError>| e.item) .map(|cx: record![y]| cx) .map(|cx: record![x, y]| cx) // GET /first/:x/:y/abc .get(path!["abc"], |cx: record![x, y]| async { "" });
pub fn handle<_P, F, Args, Ix, Pix, Fut, Resp>(
self,
method: Method,
spec: PathSpec<_P>,
handler: F
) -> Self where
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState2<L, I, P, _P, Pix, F, Args, Ix>,
[src]
self,
method: Method,
spec: PathSpec<_P>,
handler: F
) -> Self where
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState2<L, I, P, _P, Pix, F, Args, Ix>,
Register a request handler for this context's base path with spec
appended to it.
The provided handler
closure should accept an hlist argument, and return a future
that evaluates to an http response (via the Reply trait).
The argument hlist may consist of any subset of types that are present within the
context's state up to this point, or any parameters parsed from the provided path
spec
.
If an incoming request matches this route, every middleware accumulated in the context up to this point will execute. Assuming none of them short circuit with an error, this handler will then be executed.
Examples
use hyper::Body; use hyperbole::{hlist, path, record, record_args, reply::Reply, App, Hlist}; #[record_args] async fn doit(baz: f64) -> &'static str { "&'static str implements Reply" } async fn more(cx: Hlist![Body, u32]) -> &'static [u8] { b"so does &'static [u8]" } async fn using_impl(cx: Hlist![]) -> impl Reply { vec![1, 2, 3, 4, 5] } let _ctx = App::empty() .context_path(path!["foo" / "bar" / baz: f64]) .get(path!["doit"], doit) .map(|cx: record![baz]| hlist![15]) .get(path!["more" / neat: u32], more) .get(path!["more"], more) .get(path!["more" / neat: u32 / "nested"], more) .get(path!["impl_reply"], using_impl);
Panics
This method will panic if the complete path conflicts with any other route registered under the same http method.
use hyperbole::{path, record, App}; // 'a handler is already registered for path "/conflict"' let _ctx = App::empty() .context() .get(path!["conflict"], |_: record![]| async { "" }) .get(path!["conflict"], |_: record![]| async { "" });
use hyperbole::{path, record, App}; // 'wildcard ":param" conflicts with existing children in path "/:param"' let _ctx = App::empty() .context() .get(path!["something"], |_: record![]| async { "" }) .get(path![param: u32], |_: record![]| async { "" });
pub fn get<_P, F, Args, Ix, Pix, Fut, Resp>(
self,
spec: PathSpec<_P>,
handler: F
) -> Self where
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState2<L, I, P, _P, Pix, F, Args, Ix>,
[src]
self,
spec: PathSpec<_P>,
handler: F
) -> Self where
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState2<L, I, P, _P, Pix, F, Args, Ix>,
A convenience method to call handle with Method::GET .
pub fn post<_P, F, Args, Ix, Pix, Fut, Resp>(
self,
spec: PathSpec<_P>,
handler: F
) -> Self where
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState2<L, I, P, _P, Pix, F, Args, Ix>,
[src]
self,
spec: PathSpec<_P>,
handler: F
) -> Self where
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState2<L, I, P, _P, Pix, F, Args, Ix>,
A convenience method to call handle with Method::POST .
pub fn put<_P, F, Args, Ix, Pix, Fut, Resp>(
self,
spec: PathSpec<_P>,
handler: F
) -> Self where
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState2<L, I, P, _P, Pix, F, Args, Ix>,
[src]
self,
spec: PathSpec<_P>,
handler: F
) -> Self where
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState2<L, I, P, _P, Pix, F, Args, Ix>,
A convenience method to call handle with Method::PUT .
pub fn patch<_P, F, Args, Ix, Pix, Fut, Resp>(
self,
spec: PathSpec<_P>,
handler: F
) -> Self where
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState2<L, I, P, _P, Pix, F, Args, Ix>,
[src]
self,
spec: PathSpec<_P>,
handler: F
) -> Self where
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState2<L, I, P, _P, Pix, F, Args, Ix>,
A convenience method to call handle with Method::PATCH .
pub fn delete<_P, F, Args, Ix, Pix, Fut, Resp>(
self,
spec: PathSpec<_P>,
handler: F
) -> Self where
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState2<L, I, P, _P, Pix, F, Args, Ix>,
[src]
self,
spec: PathSpec<_P>,
handler: F
) -> Self where
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState2<L, I, P, _P, Pix, F, Args, Ix>,
A convenience method to call handle with Method::DELETE .
pub fn handle_with<_P, Pix, W, WArgs, WFut, Merge, E, Wix, F, Args, Fut, Resp, Ix>(
self,
method: Method,
spec: PathSpec<_P>,
with: W,
handler: F
) -> Self where
W: Fn(WArgs) -> WFut + Sync + Send,
WFut: Future<Output = Result<Merge, E>> + Send,
E: Reply,
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState3<L, I, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>,
[src]
self,
method: Method,
spec: PathSpec<_P>,
with: W,
handler: F
) -> Self where
W: Fn(WArgs) -> WFut + Sync + Send,
WFut: Future<Output = Result<Merge, E>> + Send,
E: Reply,
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState3<L, I, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>,
Register a request handler for this context's base path with spec
appended to it.
The semantics of this are mostly equivalent to handle, except for an additional with
argument, which should be a closure that could be passed to try_then. It will behave
as if added between the path combinator and handler (that is, it has access to any new
types introduced in spec
, and merges types accessible to handler
).
This is useful for specifying a different request body parser for multiple handlers that otherwise share the same chain of middlewares.
Examples
use hyperbole::{body::jsonr, path, record, App}; async fn handle_abc(cx: record![a: u32, b: String, c: f64]) -> &'static str { "neat" } let _app = App::empty() .context() .get_with(path![a: u32], jsonr::<record![b, c]>, handle_abc) .collapse();
Panics
This method will panic if the complete path conflicts with any other route registered under the same http method.
use hyperbole::{path, record, App}; use std::convert::Infallible; async fn noop(cx: record![]) -> Result<record![], Infallible> { Ok(cx) } // 'a handler is already registered for path "/conflict"' let _ctx = App::empty() .context() .get_with(path!["conflict"], noop, |_: record![]| async { "" }) .get_with(path!["conflict"], noop, |_: record![]| async { "" });
use hyperbole::{path, record, App}; use std::convert::Infallible; async fn noop(cx: record![]) -> Result<record![], Infallible> { Ok(cx) } // 'wildcard ":param" conflicts with existing children in path "/:param"' let _ctx = App::empty() .context() .get_with(path!["something"], noop, |_: record![]| async { "" }) .get_with(path![param: u32], noop, |_: record![]| async { "" });
pub fn get_with<_P, Pix, W, WArgs, WFut, Merge, E, Wix, F, Args, Fut, Resp, Ix>(
self,
spec: PathSpec<_P>,
with: W,
handler: F
) -> Self where
W: Fn(WArgs) -> WFut + Sync + Send,
WFut: Future<Output = Result<Merge, E>> + Send,
E: Reply,
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState3<L, I, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>,
[src]
self,
spec: PathSpec<_P>,
with: W,
handler: F
) -> Self where
W: Fn(WArgs) -> WFut + Sync + Send,
WFut: Future<Output = Result<Merge, E>> + Send,
E: Reply,
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState3<L, I, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>,
A convenience method to call handle_with with Method::GET .
pub fn post_with<_P, Pix, W, WArgs, WFut, Merge, E, Wix, F, Args, Fut, Resp, Ix>(
self,
spec: PathSpec<_P>,
with: W,
handler: F
) -> Self where
W: Fn(WArgs) -> WFut + Sync + Send,
WFut: Future<Output = Result<Merge, E>> + Send,
E: Reply,
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState3<L, I, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>,
[src]
self,
spec: PathSpec<_P>,
with: W,
handler: F
) -> Self where
W: Fn(WArgs) -> WFut + Sync + Send,
WFut: Future<Output = Result<Merge, E>> + Send,
E: Reply,
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState3<L, I, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>,
A convenience method to call handle_with with Method::POST .
pub fn put_with<_P, Pix, W, WArgs, WFut, Merge, E, Wix, F, Args, Fut, Resp, Ix>(
self,
spec: PathSpec<_P>,
with: W,
handler: F
) -> Self where
W: Fn(WArgs) -> WFut + Sync + Send,
WFut: Future<Output = Result<Merge, E>> + Send,
E: Reply,
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState3<L, I, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>,
[src]
self,
spec: PathSpec<_P>,
with: W,
handler: F
) -> Self where
W: Fn(WArgs) -> WFut + Sync + Send,
WFut: Future<Output = Result<Merge, E>> + Send,
E: Reply,
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState3<L, I, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>,
A convenience method to call handle_with with Method::PUT .
pub fn patch_with<_P, Pix, W, WArgs, WFut, Merge, E, Wix, F, Args, Fut, Resp, Ix>(
self,
spec: PathSpec<_P>,
with: W,
handler: F
) -> Self where
W: Fn(WArgs) -> WFut + Sync + Send,
WFut: Future<Output = Result<Merge, E>> + Send,
E: Reply,
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState3<L, I, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>,
[src]
self,
spec: PathSpec<_P>,
with: W,
handler: F
) -> Self where
W: Fn(WArgs) -> WFut + Sync + Send,
WFut: Future<Output = Result<Merge, E>> + Send,
E: Reply,
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState3<L, I, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>,
A convenience method to call handle_with with Method::PATCH .
pub fn delete_with<_P, Pix, W, WArgs, WFut, Merge, E, Wix, F, Args, Fut, Resp, Ix>(
self,
spec: PathSpec<_P>,
with: W,
handler: F
) -> Self where
W: Fn(WArgs) -> WFut + Sync + Send,
WFut: Future<Output = Result<Merge, E>> + Send,
E: Reply,
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState3<L, I, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>,
[src]
self,
spec: PathSpec<_P>,
with: W,
handler: F
) -> Self where
W: Fn(WArgs) -> WFut + Sync + Send,
WFut: Future<Output = Result<Merge, E>> + Send,
E: Reply,
F: Fn(Args) -> Fut + Sync + Send,
Fut: Future<Output = Resp> + Send,
Resp: Reply,
(): CtxState3<L, I, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>,
A convenience method to call handle_with with Method::DELETE .
pub fn collapse(self) -> App<I>
[src]
Auto Trait Implementations
impl<I, P, L> !RefUnwindSafe for Ctx<I, P, L>
impl<I, P, L> Send for Ctx<I, P, L> where
I: Send,
L: Send,
I: Send,
L: Send,
impl<I, P, L> Sync for Ctx<I, P, L> where
I: Sync,
L: Sync,
I: Sync,
L: Sync,
impl<I, P, L> Unpin for Ctx<I, P, L> where
I: Unpin,
L: Unpin,
I: Unpin,
L: Unpin,
impl<I, P, L> !UnwindSafe for Ctx<I, P, L>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<Choices> CoproductSubsetter<CNil, HNil> for Choices
[src]
type Remainder = Choices
fn subset(
self
) -> Result<CNil, <Choices as CoproductSubsetter<CNil, HNil>>::Remainder>
[src]
self
) -> Result<CNil, <Choices as CoproductSubsetter<CNil, HNil>>::Remainder>
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U, I> LiftInto<U, I> for T where
U: LiftFrom<T, I>,
[src]
U: LiftFrom<T, I>,
impl<T> Same<T> for T
type Output = T
Should always be Self
impl<Source> Sculptor<HNil, HNil> for Source
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,