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