Skip to main content

solverforge_scoring/stream/joiner/
comparison.rs

1// Comparison joiners for less than / greater than matching.
2
3use std::marker::PhantomData;
4
5use super::Joiner;
6
7/* Creates a joiner that matches when `left(a) < right(b)`.
8
9# Example
10
11```
12use solverforge_scoring::stream::joiner::{Joiner, less_than};
13
14#[derive(Clone)]
15struct Task { end: i64, start: i64 }
16
17// Task A must end before Task B starts
18let sequential = less_than(|t: &Task| t.end, |t: &Task| t.start);
19
20assert!(sequential.matches(
21&Task { end: 10, start: 0 },
22&Task { end: 20, start: 15 }
23));
24
25assert!(!sequential.matches(
26&Task { end: 10, start: 0 },
27&Task { end: 20, start: 5 }
28));
29```
30*/
31pub fn less_than<A, B, T, Fa, Fb>(left: Fa, right: Fb) -> LessThanJoiner<Fa, Fb, T>
32where
33    T: Ord,
34    Fa: Fn(&A) -> T + Send + Sync,
35    Fb: Fn(&B) -> T + Send + Sync,
36{
37    LessThanJoiner {
38        left,
39        right,
40        _phantom: PhantomData,
41    }
42}
43
44// A joiner that matches when `left(a) < right(b)`.
45pub struct LessThanJoiner<Fa, Fb, T> {
46    left: Fa,
47    right: Fb,
48    _phantom: PhantomData<fn() -> T>,
49}
50
51impl<A, B, T, Fa, Fb> Joiner<A, B> for LessThanJoiner<Fa, Fb, T>
52where
53    T: Ord,
54    Fa: Fn(&A) -> T + Send + Sync,
55    Fb: Fn(&B) -> T + Send + Sync,
56{
57    #[inline]
58    fn matches(&self, a: &A, b: &B) -> bool {
59        (self.left)(a) < (self.right)(b)
60    }
61}
62
63/* Creates a joiner that matches when `left(a) <= right(b)`.
64
65# Example
66
67```
68use solverforge_scoring::stream::joiner::{Joiner, less_than_or_equal};
69
70let joiner = less_than_or_equal(|x: &i32| *x, |y: &i32| *y);
71
72assert!(joiner.matches(&5, &10));
73assert!(joiner.matches(&5, &5));
74assert!(!joiner.matches(&10, &5));
75```
76*/
77pub fn less_than_or_equal<A, B, T, Fa, Fb>(left: Fa, right: Fb) -> LessThanOrEqualJoiner<Fa, Fb, T>
78where
79    T: Ord,
80    Fa: Fn(&A) -> T + Send + Sync,
81    Fb: Fn(&B) -> T + Send + Sync,
82{
83    LessThanOrEqualJoiner {
84        left,
85        right,
86        _phantom: PhantomData,
87    }
88}
89
90// A joiner that matches when `left(a) <= right(b)`.
91pub struct LessThanOrEqualJoiner<Fa, Fb, T> {
92    left: Fa,
93    right: Fb,
94    _phantom: PhantomData<fn() -> T>,
95}
96
97impl<A, B, T, Fa, Fb> Joiner<A, B> for LessThanOrEqualJoiner<Fa, Fb, T>
98where
99    T: Ord,
100    Fa: Fn(&A) -> T + Send + Sync,
101    Fb: Fn(&B) -> T + Send + Sync,
102{
103    #[inline]
104    fn matches(&self, a: &A, b: &B) -> bool {
105        (self.left)(a) <= (self.right)(b)
106    }
107}
108
109/* Creates a joiner that matches when `left(a) > right(b)`.
110
111# Example
112
113```
114use solverforge_scoring::stream::joiner::{Joiner, greater_than};
115
116let joiner = greater_than(|x: &i32| *x, |y: &i32| *y);
117
118assert!(joiner.matches(&10, &5));
119assert!(!joiner.matches(&5, &10));
120assert!(!joiner.matches(&5, &5));
121```
122*/
123pub fn greater_than<A, B, T, Fa, Fb>(left: Fa, right: Fb) -> GreaterThanJoiner<Fa, Fb, T>
124where
125    T: Ord,
126    Fa: Fn(&A) -> T + Send + Sync,
127    Fb: Fn(&B) -> T + Send + Sync,
128{
129    GreaterThanJoiner {
130        left,
131        right,
132        _phantom: PhantomData,
133    }
134}
135
136// A joiner that matches when `left(a) > right(b)`.
137pub struct GreaterThanJoiner<Fa, Fb, T> {
138    left: Fa,
139    right: Fb,
140    _phantom: PhantomData<fn() -> T>,
141}
142
143impl<A, B, T, Fa, Fb> Joiner<A, B> for GreaterThanJoiner<Fa, Fb, T>
144where
145    T: Ord,
146    Fa: Fn(&A) -> T + Send + Sync,
147    Fb: Fn(&B) -> T + Send + Sync,
148{
149    #[inline]
150    fn matches(&self, a: &A, b: &B) -> bool {
151        (self.left)(a) > (self.right)(b)
152    }
153}
154
155/* Creates a joiner that matches when `left(a) >= right(b)`.
156
157# Example
158
159```
160use solverforge_scoring::stream::joiner::{Joiner, greater_than_or_equal};
161
162let joiner = greater_than_or_equal(|x: &i32| *x, |y: &i32| *y);
163
164assert!(joiner.matches(&10, &5));
165assert!(joiner.matches(&5, &5));
166assert!(!joiner.matches(&5, &10));
167```
168*/
169pub fn greater_than_or_equal<A, B, T, Fa, Fb>(
170    left: Fa,
171    right: Fb,
172) -> GreaterThanOrEqualJoiner<Fa, Fb, T>
173where
174    T: Ord,
175    Fa: Fn(&A) -> T + Send + Sync,
176    Fb: Fn(&B) -> T + Send + Sync,
177{
178    GreaterThanOrEqualJoiner {
179        left,
180        right,
181        _phantom: PhantomData,
182    }
183}
184
185// A joiner that matches when `left(a) >= right(b)`.
186pub struct GreaterThanOrEqualJoiner<Fa, Fb, T> {
187    left: Fa,
188    right: Fb,
189    _phantom: PhantomData<fn() -> T>,
190}
191
192impl<A, B, T, Fa, Fb> Joiner<A, B> for GreaterThanOrEqualJoiner<Fa, Fb, T>
193where
194    T: Ord,
195    Fa: Fn(&A) -> T + Send + Sync,
196    Fb: Fn(&B) -> T + Send + Sync,
197{
198    #[inline]
199    fn matches(&self, a: &A, b: &B) -> bool {
200        (self.left)(a) >= (self.right)(b)
201    }
202}