[][src]Struct hyperbole::Ctx

pub struct Ctx<I, P, L> { /* fields omitted */ }

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:

  1. An hlist provided at App initialization time (via App::new or App::empty).
  2. An hlist generated from incoming http request parts.
  3. 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.

This example deliberately fails to compile
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]

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

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]

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]

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]

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]

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]

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]

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]

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]

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.

This example panics
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 { "" });
This example panics
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]

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]

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]

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]

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]

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]

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.

This example panics
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 { "" });
This example panics
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]

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]

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]

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]

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]

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

pub fn collapse(self) -> App<I>[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).

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

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

impl<I, P, L> Unpin for Ctx<I, P, L> where
    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]

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, 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.