Skip to content
This repository has been archived by the owner on Jan 18, 2020. It is now read-only.

Reimplement combinators #174

Closed
14 tasks
ubnt-intrepid opened this issue Apr 7, 2018 · 2 comments
Closed
14 tasks

Reimplement combinators #174

ubnt-intrepid opened this issue Apr 7, 2018 · 2 comments
Milestone

Comments

@ubnt-intrepid
Copy link
Contributor

ubnt-intrepid commented Apr 7, 2018

See #174 (comment) for detailed design.

Tasks

  • Add/Modify combinators and core primitives
    • map
    • then
    • inspect
    • and
    • or
    • left
    • right
    • try_abort
    • ok
  • Add/Modify HTTP primitives
    • body
    • segment
    • path
    • header
    • method
@ubnt-intrepid
Copy link
Contributor Author

ubnt-intrepid commented Apr 7, 2018

The definition of Endpoint

A candidate for the new definition of Endpoint is described as follows:

trait Endpoint {
    type Item;
    type Future: Future<Item = Self::Item, Error = Error>;
    fn apply(&self, input: &Input, cx: &mut Context) -> Option<Self::Future>;
}

Future::Error is restricted to Error. This associated type represents an unrecoverable error occurring after constructing a task from the returned Future. With some exceptions, most combinators will be designed so that this variant does not exist on the surface.

Error

The type Error represents all kind of errors during processing the incoming HTTP request.
This error type is described as an enum which has the following two variants:

enum ErrorKind {
    /// The matched route was not found (i.e. Endpoint::apply() returned a `None`)
    Canceled,

    /// The handling was aborted *after* creating the future.
    Aborted(Box<HttpError>),
}

Combinators

The combinators are provided as the methods of sub-traits. Some methods are intentionally analogous to the new Future API.

Universal combinators:

trait EndpointExt: Endpoint {
    fn map<U>(self, f: impl FnOnce(Self::Item) -> U + Clone) -> impl Endpoint<Item = U>;

    fn then<F>(self, f: impl FnOnce(Self::Item) -> F + Clone) -> impl Endpoint<Item = F::Item>
    where F: IntoFuture<Error = !>;

    fn and_then<F, U>(self, impl FnOnce(Self::Item) -> F + Clone) -> impl Endpoint<Item = U>
    where F: IntoFuture<Item = U>,
          F::Error: HttpError;

    fn and<E>(self, e: E) -> impl Endpoint<Item = (Self::Item, E::Item)>
    where E: IntoEndpoint;

    fn or<E>(self, e: E) -> impl Endpoint<Item = Self::Item>
    where E: IntoEndpoint<Item = Self::Item>;

    fn left<E>(self, e: E) -> impl Endpoint<Item = Self::Item>
    where E: IntoEndpoint;

    fn right<E>(self, e: E) -> impl Endpoint<Item = E::Item>
    where E: IntoEndpoint;

    fn try_abort(self, impl FnOnce(Self::Item) -> Result<T, E> + Clone) -> impl Endpoint<Item = T>
    where E: HttpError;
}

Note that all FnOnce + Clone bounds will be replaced with Fn when allowing non-clonable closures.

Common primitives

fn ok<T: Clone>(x: T) -> impl Endpoint<Item = T> { ... }

HTTP primitives

Although there are no major changes in the prepared HTTP primitives, the implementation will be once reviewed in order to carefully select the necessary items (the details is omitted here).

@ubnt-intrepid ubnt-intrepid changed the title Stop using the associated type Error in Future Reimplement combinators Apr 8, 2018
@ubnt-intrepid ubnt-intrepid added this to the 0.11.0 milestone Apr 8, 2018
@ubnt-intrepid
Copy link
Contributor Author

original comment:


The futures team has published an RFC for standardization of Future API, and it describes a policy to remove the associated type Error from Future. This RFC is currently before approval and it is not necessary to respond immediately, but it is possible to remove using Error with the current dependency of 0.1.

In order to avoid future design changes, it would be desirable to switch to the policy that eliminates the use of Errors at this time.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant