finchers_ext/
lib.rs

1//! Extensions for constructing Endpoints
2
3#![doc(html_root_url = "https://docs.rs/finchers-ext/0.11.0")]
4#![deny(missing_docs)]
5#![deny(missing_debug_implementations)]
6#![deny(warnings)]
7
8extern crate either;
9#[macro_use]
10extern crate finchers_core;
11
12pub mod option;
13pub mod result;
14
15mod abort;
16mod all;
17mod and;
18mod inspect;
19mod just;
20mod lazy;
21mod left;
22mod lift;
23mod map;
24mod map_async;
25mod maybe_done;
26mod or;
27mod right;
28
29// re-exports
30pub use abort::{abort, Abort};
31pub use all::{all, All};
32pub use and::And;
33pub use inspect::Inspect;
34pub use just::{just, Just};
35pub use lazy::{lazy, Lazy};
36pub use left::Left;
37pub use lift::Lift;
38pub use map::Map;
39pub use map_async::MapAsync;
40pub use or::Or;
41pub use right::Right;
42
43#[doc(inline)]
44pub use option::EndpointOptionExt;
45#[doc(inline)]
46pub use result::EndpointResultExt;
47
48// ==== EndpointExt ===
49
50use finchers_core::endpoint::{assert_output, Endpoint, IntoEndpoint};
51use finchers_core::task::IntoTask;
52
53/// A set of extension methods used for composing complicate endpoints.
54pub trait EndpointExt: Endpoint + Sized {
55    /// Annotate that the associated type `Output` is equal to `T`.
56    #[inline(always)]
57    fn as_t<T>(self) -> Self
58    where
59        Self: Endpoint<Output = T>,
60    {
61        self
62    }
63
64    /// Create an endpoint which evaluates `self` and `e` and returns a pair of their tasks.
65    ///
66    /// The returned future from this endpoint contains both futures from
67    /// `self` and `e` and resolved as a pair of values returned from theirs.
68    fn and<E>(self, e: E) -> And<Self, E::Endpoint>
69    where
70        E: IntoEndpoint,
71        Self::Output: Send,
72        E::Output: Send,
73    {
74        assert_output::<_, (Self::Output, <E::Endpoint as Endpoint>::Output)>(self::and::new(self, e))
75    }
76
77    /// Create an endpoint which evaluates `self` and `e` and returns the task of `self` if matched.
78    fn left<E>(self, e: E) -> Left<Self, E::Endpoint>
79    where
80        E: IntoEndpoint,
81    {
82        assert_output::<_, Self::Output>(self::left::new(self, e))
83    }
84
85    /// Create an endpoint which evaluates `self` and `e` and returns the task of `e` if matched.
86    fn right<E>(self, e: E) -> Right<Self, E::Endpoint>
87    where
88        E: IntoEndpoint,
89    {
90        assert_output::<_, E::Output>(self::right::new(self, e))
91    }
92
93    /// Create an endpoint which evaluates `self` and `e` sequentially.
94    ///
95    /// The returned future from this endpoint contains the one returned
96    /// from either `self` or `e` matched "better" to the input.
97    fn or<E>(self, e: E) -> Or<Self, E::Endpoint>
98    where
99        E: IntoEndpoint<Output = Self::Output>,
100    {
101        assert_output::<_, Self::Output>(self::or::new(self, e))
102    }
103
104    /// Create an endpoint which returns `None` if the inner endpoint skips the request.
105    fn lift(self) -> Lift<Self> {
106        assert_output::<_, Option<Self::Output>>(self::lift::new(self))
107    }
108
109    /// Create an endpoint which maps the returned value to a different type.
110    fn map<F, U>(self, f: F) -> Map<Self, F>
111    where
112        F: FnOnce(Self::Output) -> U + Clone + Send + Sync,
113    {
114        assert_output::<_, F::Output>(self::map::new(self, f))
115    }
116
117    /// Create an endpoint which do something with the output value from `self`.
118    fn inspect<F>(self, f: F) -> Inspect<Self, F>
119    where
120        F: FnOnce(&Self::Output) + Clone + Send + Sync,
121    {
122        assert_output::<_, Self::Output>(self::inspect::new(self, f))
123    }
124
125    /// Create an endpoint which continue an asynchronous computation
126    /// from the value returned from `self`.
127    fn map_async<F, T>(self, f: F) -> MapAsync<Self, F>
128    where
129        F: FnOnce(Self::Output) -> T + Clone + Send + Sync,
130        T: IntoTask,
131        T::Task: Send,
132    {
133        assert_output::<_, T::Output>(self::map_async::new(self, f))
134    }
135}
136
137impl<E: Endpoint> EndpointExt for E {}