1#![allow(missing_docs)]
2
3use either::Either;
4use finchers_core::endpoint::{Context, Endpoint, IntoEndpoint};
5
6pub fn new<E1, E2>(e1: E1, e2: E2) -> Or<E1::Endpoint, E2::Endpoint>
7where
8 E1: IntoEndpoint,
9 E2: IntoEndpoint<Output = E1::Output>,
10{
11 Or {
12 e1: e1.into_endpoint(),
13 e2: e2.into_endpoint(),
14 }
15}
16
17#[derive(Debug, Copy, Clone)]
18pub struct Or<E1, E2> {
19 e1: E1,
20 e2: E2,
21}
22
23impl<E1, E2> Endpoint for Or<E1, E2>
24where
25 E1: Endpoint,
26 E2: Endpoint<Output = E1::Output>,
27{
28 type Output = E1::Output;
29 type Task = Either<E1::Task, E2::Task>;
30
31 fn apply(&self, cx2: &mut Context) -> Option<Self::Task> {
32 let mut cx1 = cx2.clone();
33 let t1 = self.e1.apply(&mut cx1);
34 let t2 = self.e2.apply(cx2);
35 match (t1, t2) {
36 (Some(t1), Some(t2)) => {
37 let res = if cx1.segments().popped() > cx2.segments().popped() {
40 *cx2 = cx1;
41 Either::Left(t1)
42 } else {
43 Either::Right(t2)
44 };
45 Some(res)
46 }
47 (Some(t1), None) => {
48 *cx2 = cx1;
49 Some(Either::Left(t1))
50 }
51 (None, Some(t2)) => Some(Either::Right(t2)),
52 (None, None) => None,
53 }
54 }
55}