finchers_ext/option/
ok_or_else.rs

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