finchers_ext/
map.rs

1#![allow(missing_docs)]
2
3use finchers_core::endpoint::{Context, Endpoint, IntoEndpoint};
4use finchers_core::task::{self, Task};
5use finchers_core::{Error, PollResult};
6
7pub fn new<E, F, T>(endpoint: E, f: F) -> Map<E::Endpoint, F>
8where
9    E: IntoEndpoint,
10    F: FnOnce(E::Output) -> T + Clone + Send + Sync,
11{
12    Map {
13        endpoint: endpoint.into_endpoint(),
14        f,
15    }
16}
17
18#[derive(Copy, Clone, Debug)]
19pub struct Map<E, F> {
20    endpoint: E,
21    f: F,
22}
23
24impl<E, F, T> Endpoint for Map<E, F>
25where
26    E: Endpoint,
27    F: FnOnce(E::Output) -> T + Clone + Send + Sync,
28{
29    type Output = F::Output;
30    type Task = MapTask<E::Task, F>;
31
32    fn apply(&self, cx: &mut Context) -> Option<Self::Task> {
33        Some(MapTask {
34            task: self.endpoint.apply(cx)?,
35            f: Some(self.f.clone()),
36        })
37    }
38}
39
40#[derive(Debug)]
41pub struct MapTask<T, F> {
42    task: T,
43    f: Option<F>,
44}
45
46impl<T, F, U> Task for MapTask<T, F>
47where
48    T: Task + Send,
49    F: FnOnce(T::Output) -> U + Send,
50{
51    type Output = U;
52
53    fn poll_task(&mut self, cx: &mut task::Context) -> PollResult<Self::Output, Error> {
54        self.task.poll_task(cx).map_ok(|item| {
55            let f = self.f.take().expect("cannot resolve twice");
56            cx.input().enter_scope(|| f(item))
57        })
58    }
59}