[][src]Struct hyperbole::Ctx

pub struct Ctx<P, L, S = ()> { /* fields omitted */ }

A request processing context.

In effect, this represents a cumulative builder-pattern constructor for request handlers.

Strongly typed request scoped state

The core abstraction used within this struct is an hlist of request scoped state paired with a composable chain of middlewares that transform it.

Each Ctx state starts life as an Init, and is modified through successive application of various middleware combinators (such as map, then, try_map, path, etc).

use hyper::Uri;
use hyperbole::{Ctx, R, r};

let _ctx = Ctx::default()
    // a no-op middleware which doesn't modify the state
    .map(|cx: R![]| cx)
    // a middleware that adds a `usize` to the state, based on the uri
    .map(|cx: R![Uri]| r![cx.head.path().len(), ...cx])
    // a middlware that consumes the uri, and adds nothing
    .map(|cx: R![Uri]| r![]);

Handling requests

At any point, a handler function may be registered for a given route. The handler will execute after any middlewares that have been composed prior to it, and will likewise have access to any of the accumulated state.

New middlewares do not retroactively apply to handlers that have already been registered. Only the middlewares logically prior to a handler's registration will be folded into that handler.

Unlike middlewares - which return new state - handlers should return a value which implements Reply.

use hyperbole::{r, uri, Ctx, R};

let _ctx = Ctx::default()
    .map(|_: R![]| r!["hello worldo"])
    // only the above `map` is executed before this handler
    .get(uri!["some-route"], |cx: R![&str]| async move {
        format!("message: {:?}", cx.head)
    })
    .map(|_: R![]| r![3.14159])
    // but this handler is preceded by both `map`s
    .get(uri!["another"], |cx: R![&str, f64]| async move {
        format!("message: {:?}, number: {}", cx.head, cx.tail.head)
    });

Parsing request uris

Parameters in uris can be described with the uri! macro. Much like middlewares, path parsers merge new elements into the request scoped state.

use hyperbole::{r, record_args, uri, Ctx, R};

#[derive(Debug)]
struct Widget;

#[record_args]
fn retrieve_widget(widget_id: u64) -> R![Widget] {
    r![Widget]
}

let _widget_ctx = Ctx::default()
    .path(uri!["widgets" / widget_id: u64])
    .map(retrieve_widget)
    .get(uri!["show"], |cx: R![Widget]| async move {
        format!("{:?}", cx.head)
    });

Error handling and flow control

Errors that may arise during request resolution are represented in the context as an exhaustive coproduct (a generalization of enums). When a fallible middleware is applied (in try_map or try_then), an additional variant is appended to said 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, falling over to the error handling execution path. The specific error response returned to the client can be modified in a map_errs or map_err combinator; the former transforming the complete error coproduct and the latter a single variant of it.

use hyperbole::{record_args, tree::UriError, uri, Ctx, R};
use std::num::ParseIntError;

#[derive(Debug)]
struct Widget;

#[record_args]
fn retrieve_widget(widget_id: u64) -> Result<R![Widget], &'static str> {
    Err("bad news")
}

let _widget_ctx = Ctx::default()
    .path(uri!["widgets" / widget_id: u64])
    .try_map(retrieve_widget)
    .map_err(|e: UriError<ParseIntError>| {
        println!("failed to parse {:?} as a u64: {}", e.item, e.err);
        e
    })
    .map_err(|e: &str| {
        println!("failed to retrieve widget: {}", e);
        e
    })
    .get(uri!["show"], |cx: R![Widget]| async move {
        format!("{:?}", cx.head)
    });

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.

This example deliberately fails to compile
use hyperbole::{r, Ctx, R};

struct A(u32);

let _ctx = Ctx::default()
    // merge an A
    .map(|cx: R![]| r![A(1)])
    // merge an A (state now contains two `A`s)
    .map(|cx: R![]| r![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: R![A]| cx);

Named fields can be used to disambiguate between what would otherwise be duplicate types. In particular, the uri! macro 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::{r, Ctx, R};

struct A(u32);

let _ctx = Ctx::default()
    .map(|cx: R![]| r![first = A(1)])
    .map(|cx: R![]| r![second = A(2)])
    // we want the A called 'second'
    .map(|cx: R![second: A]| cx)
    // we want the A called 'first'
    .map(|cx: R![first: A]| cx)
    // we want both of them
    .map(|cx: R![first: A, second: A]| cx);

Implementations

impl<P: HList + Send + Parser<Segment>> Ctx<Params<P>, Path<Base, P, Here>>[src]

pub fn with_path(spec: PathSpec<P>) -> Self[src]

Create a new request context at the provided base path. Any parameters parsed from the uri will be merged into the context's state.

The uri! macro can be used to construct an appropriate PathSpec.

Examples

use hyperbole::{r, uri, Ctx, R};

let _ctx = Ctx::with_path(uri!["foo" / "bar" / baz: f64])
    .map(|cx: R![baz: _]| r![qux = *cx.head > 3.14159265])
    .map(|cx: R![qux: _]| cx);

impl<T: Clone> Ctx<HNil, InjectAll<Base, T>> where
    InjectAll<Base, T>: Link<Init, HNil>, 
[src]

pub fn with_state(values: T) -> Self[src]

Create a new request context with an hlist of cloneable values. All elements of values will be merged into the context's state.

Examples

use hyperbole::{r, Ctx, R};

let _ctx = Ctx::with_state(r![x = 4, y = "hello", z = "world"])
    .map(|cx: R![x: _]| cx)
    .map(|cx: R![y: _, z: _]| cx)
    .map(|cx: R![z: _, x: _, y: _]| cx);

impl<P: 'static, L: Sync + Send + Clone + 'static, S> Ctx<P, L, S>[src]

pub fn inject<T: Clone>(self, value: T) -> Ctx<P, Inject<L, T>, S> where
    Inject<L, T>: Link<Init, P>, 
[src]

Inject a cloneable value into the request scoped state.

Examples

use hyperbole::{f, r, Ctx, R};

let _ctx = Ctx::default()
    .inject("just an &str")
    .map(|cx: R![&str]| r![])
    .inject(f![xyz = "this is a named field"])
    .map(|cx: R![xyz: _]| r![]);

pub fn inject_all<T: Clone>(self, values: T) -> Ctx<P, InjectAll<L, T>, S> where
    InjectAll<L, T>: Link<Init, P>, 
[src]

Inject an hlist of cloneable values into the request scoped state.

Examples

use hyperbole::{r, Ctx, R};

let _ctx = Ctx::default()
    .inject_all(r![a = "foobar", b = 42])
    .map(|cx: R![b: _, a: _]| cx)
    .inject_all(r![c = ()])
    .map(|cx: R![a: _, b: _, c: _]| cx);

pub fn map<F, Args, Ix, Merge>(self, f: F) -> Ctx<P, Map<L, F, Args, Ix>, S> where
    F: Fn(Args) -> Merge,
    Merge: HList,
    Map<L, F, Args, Ix>: Link<Init, P>, 
[src]

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::{r, record_args, Ctx, R};

#[record_args]
fn fun(_: Body, _: u32) -> R![] {
    r![]
}

let _ctx = Ctx::default()
    .map(|cx: R![Body]| cx)
    .map(|cx: R![]| r![12345])
    .map(fun);

pub fn try_map<F, Args, Ix, Merge, E>(
    self,
    f: F
) -> Ctx<P, TryMap<L, F, Args, Ix>, S> where
    F: Fn(Args) -> Result<Merge, E>,
    Merge: HList,
    E: Reply,
    TryMap<L, F, Args, Ix>: Link<Init, P>, 
[src]

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::{uri, zoom, Ctx, R};

let _ctx = Ctx::with_path(uri![a: u32 / b: u32])
    .try_map(|cx: R![a: _, b: _]| match zoom!(&cx.a) > zoom!(&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<P, Then<L, F, Args, Ix>, S> where
    F: Fn(Args) -> Fut,
    Fut: Future<Output = Merge>,
    Merge: HList,
    Then<L, F, Args, Ix>: Link<Init, P>, 
[src]

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::{r, record_args, Ctx, R};

#[record_args]
async fn fun(_: Body) -> R![] {
    r![]
}

let _ctx = Ctx::default()
    .then(|cx: R![Body]| async move { cx })
    .then(|cx: R![]| async move { cx })
    .then(fun);

pub fn try_then<F, Args, Ix, Fut, Merge, E>(
    self,
    f: F
) -> Ctx<P, TryThen<L, F, Args, Ix>, S> where
    F: Fn(Args) -> Fut,
    Fut: Future<Output = Result<Merge, E>>,
    Merge: HList,
    E: Reply,
    TryThen<L, F, Args, Ix>: Link<Init, P>, 
[src]

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::{r, uri, Ctx, R};

let _ctx = Ctx::with_path(uri![a: f64 / b: String])
    .try_then(|cx: R![a: f64, b: String]| async move {
        let (a, b) = cx.into();
        if *a == 3.14159265 && *b != "blue" {
            Err("always blue!")
        } else {
            Ok(r![color = "it was blue!"])
        }
    })
    .map(|cx: R![color: _]| cx);

pub fn map_errs<F, E>(self, f: F) -> Ctx<P, MapErrs<L, F>, S> where
    F: Fn(<L as Link<Init, P>>::Error) -> E,
    E: Reply,
    L: Link<Init, P>,
    MapErrs<L, F>: Link<Init, P>, 
[src]

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 frunk_core::Coprod;
use hyperbole::{Ctx, R};

let _ctx = Ctx::default()
    // without any fallible combinators, the error is an uninhabitable enum:
    .map_errs(|err: Coprod![]| -> Coprod![] { match err {} })
    .map(|cx: R![]| cx);

pub fn map_err<F, E, Ix, R>(self, f: F) -> Ctx<P, MapErr<L, F, E, Ix>, S> where
    F: Fn(E) -> R,
    R: Reply,
    MapErr<L, F, E, Ix>: Link<Init, P>, 
[src]

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 may have occurred, this will only affect the most recent of them.

Examples

use hyperbole::{record_args, Ctx, R};

fn fallible_a(_: R![]) -> Result<R![], String> {
    Err("uh oh".to_owned())
}

#[record_args]
fn fallible_b() -> Result<R![], Vec<u8>> {
    Err(b"uh oh".to_vec())
}

let _ctx = Ctx::default()
    .try_map(fallible_a)
    .try_map(fallible_b)
    .map_err(|e: String| "it was String")
    .map_err(|e: Vec<u8>| "it was Vec<u8>");

pub fn path<_P, Ix>(
    self,
    spec: PathSpec<_P>
) -> Ctx<<P as Add<Params<_P>>>::Output, Path<L, _P, Ix>, S> where
    P: Add<Params<_P>>,
    _P: Parser<Segment>,
    Path<L, _P, Ix>: Link<Init, <P as Add<Params<_P>>>::Output>, 
[src]

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 uri! 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::{tree::UriError, uri, Ctx, R};
use std::num::ParseFloatError;

let _ctx = Ctx::default()
    .path(uri!["first" / x: usize / y: f64])
    .map(|cx: R![x: _]| cx)
    .map_err(|e: UriError<ParseFloatError>| e.item)
    .map(|cx: R![y: _]| cx)
    .map(|cx: R![x: _, y: _]| cx)
    // GET /first/:x/:y/abc
    .get(uri!["abc"], |cx: R![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, P, _P, Pix, F, Args, Ix>, 
[src]

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::{r, record_args, reply::Reply, uri, Ctx, R};

#[record_args]
async fn doit(baz: f64) -> &'static str {
    "&'static str implements Reply"
}

async fn more(cx: R![Body, u32]) -> &'static [u8] {
    b"so does &'static [u8]"
}

async fn using_impl(cx: R![]) -> impl Reply {
    vec![1, 2, 3, 4, 5]
}

let _ctx = Ctx::with_path(uri!["foo" / "bar" / baz: f64])
    .get(uri!["doit"], doit)
    .map(|cx: R![baz: _]| r![15])
    .get(uri!["more"], more)
    .get(uri!["more" / neat: u32], more)
    .get(uri!["more" / neat: u32 / "nested"], more)
    .get(uri!["impl_reply"], using_impl);

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, P, _P, Pix, F, Args, Ix>, 
[src]

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, P, _P, Pix, F, Args, Ix>, 
[src]

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, P, _P, Pix, F, Args, Ix>, 
[src]

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, P, _P, Pix, F, Args, Ix>, 
[src]

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, P, _P, Pix, F, Args, Ix>, 
[src]

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, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>, 
[src]

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, record_args, uri, Ctx, R};

async fn handle_abc(cx: R![a: u32, b: String, c: f64]) -> &'static str {
    "neat"
}

#[record_args]
async fn handle_cba(c: f64, b: String, a: u32) -> &'static str {
    "neat"
}

let _ctx = Ctx::default()
    .get_with(uri!["1" / a: u32], jsonr::<R![b: _, c: _]>, handle_abc)
    .get_with(uri!["2" / a: u32], jsonr::<R![b: _, c: _]>, handle_cba);

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, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>, 
[src]

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, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>, 
[src]

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, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>, 
[src]

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, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>, 
[src]

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, P, _P, Pix, W, WArgs, Wix, F, Args, Ix>, 
[src]

A convenience method to call handle_with with Method::DELETE .

pub fn into_routes(self) -> Routes[src]

Collapse this context and retrieve any routes registered via handle (or helpers like get, post, etc).

impl<P: 'static, L: Sync + Send + Clone + 'static> Ctx<P, L, App>[src]

pub fn collapse(self) -> App[src]

Collapse this context and return to the base App.

This discards any accumulated combinators and path specifications, while retaining handlers registered via handle (or helpers like get, post, etc).

Panics

This method panics if any registered handler paths (with the same method) conflict with eachother or any routes in the App.

This example panics
use hyperbole::{uri, App, R};

// 'a handler is already registered for path "/conflict"'
let _app = App::new()
    .context()
    .get(uri!["conflict"], |_: R![]| async { "" })
    .get(uri!["conflict"], |_: R![]| async { "" })
    .collapse();
This example panics
use hyperbole::{uri, App, R};

// 'wildcard ":param" conflicts with existing children in path "/:param"'
let _app = App::new()
    .context()
    .get(uri!["something"], |_: R![]| async { "" })
    .get(uri![param: u32], |_: R![]| async { "" })
    .collapse();

Trait Implementations

impl Default for Ctx<HNil, Base>[src]

Auto Trait Implementations

impl<P, L, S = ()> !RefUnwindSafe for Ctx<P, L, S>

impl<P, L, S> Send for Ctx<P, L, S> where
    L: Send,
    S: Send

impl<P, L, S> Sync for Ctx<P, L, S> where
    L: Sync,
    S: Sync

impl<P, L, S> Unpin for Ctx<P, L, S> where
    L: Unpin,
    S: Unpin

impl<P, L, S = ()> !UnwindSafe for Ctx<P, L, S>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<Choices> CoproductSubsetter<CNil, HNil> for Choices[src]

type Remainder = Choices

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U, I> LiftInto<U, I> for T where
    U: LiftFrom<T, I>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

impl<Source> Sculptor<HNil, HNil> for Source[src]

type Remainder = Source

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.