Skip to main content

common_range_tools/
builder.rs

1use std::ops::RangeInclusive;
2use std::{
3    marker::PhantomData,
4    ops::{Add, Bound, Sub},
5};
6
7use crate::{GetBeginEnd, Mrs};
8
9/// The **Number Implementation** of [IncDecCpCmp].  
10///
11/// Acts as the general proxy layer for safly working with primitive number types inside [crate].
12/// Note: unlike [AnyIncDecCpCmp], the self.inc(a,b) and self.dec(a,b) are checked.
13///
14/// The following types are implemented for [NumberIncDecCpCmp]
15///  - [u8], [u16], [u32], [u64], [u128], [usize]
16///  - [i8], [i16], [i32], [i64], [i128], [isize]
17///  - [f32], [f64]
18#[derive(Clone, Copy, Debug)]
19pub struct NumberIncDecCpCmp<T>
20where
21    T: Copy + Clone,
22{
23    min: T,
24    max: T,
25}
26
27/// The **Generic Implementation** of [IncDecCpCmp].
28///
29/// Acts as the general proxy layer for working with any type inside [crate].
30///
31/// Note: unlike [NumberIncDecCpCmp], the self.inc(a,b) and self.dec(a,b) are unchecked!
32/// If you are working with primitive numbers use: [NumberIncDecCpCmp] in stead.
33#[derive(Clone, Copy, Debug)]
34pub struct AnyIncDecCpCmp<T>
35where
36    T: PartialOrd + Clone + Copy,
37{
38    min: T,
39    max: T,
40}
41impl<T> AnyIncDecCpCmp<T>
42where
43    T: PartialOrd + Clone + Copy,
44{
45    pub fn new(min: T, max: T) -> Self {
46        Self { min, max }
47    }
48
49    /// Sets the values returned by self.min() and self.min_ref().
50    /// Changing this value from the default will further constrain what ranges are considered invalid.
51    pub fn set_min(&mut self, v: T) {
52        self.min = v;
53    }
54
55    /// Sets the values returned by self.max() and self.max_ref().
56    /// Changing this value from the default will further constrain what ranges are considered invalid.
57    pub fn set_max(&mut self, v: T) {
58        self.max = v;
59    }
60}
61
62impl<T> CpCmp<T> for AnyIncDecCpCmp<T>
63where
64    T: PartialOrd + Copy,
65{
66    /// Returns a copy of v.
67    fn cp(&self, v: &T) -> T {
68        return *v;
69    }
70
71    /// Returns a ref to self.min.
72    fn min_ref(&self) -> &T {
73        return &self.min;
74    }
75
76    /// Returns a ref to self.max.
77    fn max_ref(&self) -> &T {
78        return &self.max;
79    }
80
81    /// Returns true if a lt b.
82    fn lt(&self, a: &T, b: &T) -> bool {
83        return a < b;
84    }
85
86    /// Returns a copy of min.
87    fn min(&self) -> T {
88        return self.min;
89    }
90
91    /// Returns a copy of max.
92    fn max(&self) -> T {
93        return self.max;
94    }
95}
96
97impl<T, V> IncDecCpCmp<T, V> for AnyIncDecCpCmp<T>
98where
99    V: Copy,
100    T: PartialOrd + Copy + Add<V, Output = T> + Sub<V, Output = T>,
101{
102    /// Increments a by b, if the resulting value is le a None is returned.
103    fn inc(&self, a: &T, b: &V) -> Option<T> {
104        let x = *a;
105        let c = a.add(*b);
106        if x <= c {
107            return Some(c);
108        }
109        return None;
110    }
111
112    /// Increments a by b, if the resulting value is ge a None is returned.
113    fn dec(&self, a: &T, b: &V) -> Option<T> {
114        let x = *a;
115        let c = a.sub(*b);
116        if x >= c {
117            return Some(c);
118        }
119        return None;
120    }
121
122    fn cp_v(&self, v: &V) -> V {
123        return *v;
124    }
125}
126impl<T> NumberIncDecCpCmp<T>
127where
128    T: Clone + Copy,
129    NumberIncDecCpCmp<T>: DefaultValues<T, T>,
130{
131    pub fn defaults() -> Self {
132        return Self::new(
133            NumberIncDecCpCmp::default_min(),
134            NumberIncDecCpCmp::default_max(),
135        );
136    }
137    pub fn new(min: T, max: T) -> Self {
138        Self { min, max }
139    }
140
141    /// Sets the values returned by self.min() and self.min_ref().
142    /// Changing this value from the default will further constrain what ranges are considered invalid.
143    pub fn set_min(&mut self, v: T) {
144        self.min = v;
145    }
146
147    /// Sets the values returned by self.max() and self.max_ref().
148    /// Changing this value from the default will further constrain what ranges are considered invalid.
149    pub fn set_max(&mut self, v: T) {
150        self.max = v;
151    }
152}
153
154/// **Copy and Compare Values**
155///
156/// For an implementation examples and details see: [IncDecCpCmp].
157pub trait CpCmp<T> {
158    //. Should return a clone or copy of &T.
159    fn cp(&self, v: &T) -> T;
160
161    fn min_ref(&self) -> &T;
162    fn max_ref(&self) -> &T;
163
164    /// Returns true if a < b.
165    fn lt(&self, a: &T, b: &T) -> bool;
166
167    /// Returns the minimum begin value we will accept when converting from [`std::ops::Bound::Unbounded`].
168    fn min(&self) -> T;
169
170    /// Returns the maximum end value we will accept when converting from [`std::ops::Bound::Unbounded`].
171    fn max(&self) -> T;
172
173    /// Returns true if a gt b.
174    fn gt(&self, a: &T, b: &T) -> bool {
175        return self.lt(b, a);
176    }
177
178    /// Returns true if a eq b.
179    fn eq(&self, a: &T, b: &T) -> bool {
180        return !self.lt(a, b) && !self.lt(b, a);
181    }
182
183    /// Returns true if a ne b.
184    fn ne(&self, a: &T, b: &T) -> bool {
185        return self.lt(a, b) || self.lt(b, a);
186    }
187
188    /// Returns true if a le b.
189    fn le(&self, a: &T, b: &T) -> bool {
190        return self.lt(a, b) || !self.lt(b, a);
191    }
192
193    /// Returns true if a ge b.
194    fn ge(&self, a: &T, b: &T) -> bool {
195        return self.lt(b, a) || !self.lt(a, b);
196    }
197
198    /// Returns true if a and b contain c.
199    fn contains(&self, a: &T, b: &T, c: &T) -> bool {
200        return !(self.lt(c, a) || self.lt(b, c));
201    }
202
203    /// Returns a new owned copy of the input ref tuple.
204    fn cp_tpl_ref(&self, src: (&T, &T)) -> (T, T) {
205        return (self.cp(src.0), self.cp(src.1));
206    }
207
208    /// Returns true if any of the following are true
209    /// - a and b contain c
210    /// - a and b contain d
211    /// - c and d contain a
212    /// - c and d contain b
213    fn overlap(&self, a: &T, b: &T, c: &T, d: &T) -> bool {
214        return self.contains(a, b, c)
215            || self.contains(a, b, d)
216            || self.contains(c, d, a)
217            || self.contains(c, d, b);
218    }
219
220    /// Returns true if b lt a or a lt self.min_ref() or self.max_ref() lt b.
221    fn is_invalid_set(&self, a: &T, b: &T) -> bool {
222        return self.lt(b, a) || self.lt(a, self.min_ref()) || self.lt(self.max_ref(), b);
223    }
224}
225
226/// **Increment, Decrement, Copy, Compare Values and Ranges**
227///
228/// This is the base trait used to represent range manipulation by [crate].  
229/// In general this library implements the proxy or wrapper approach to range and value manipulation as apposed to
230/// manipulation by value.  This means the trait implementation for values does not need to be implemented on the generic type.
231/// Since the operations are not implemented by the values, this frees us from the worry of conflicting trait resoltion.   This
232/// also means we can quickly implement how the values and ranges are manipualted for the same data for a different task.
233///
234/// Example Implementation
235///
236/// ```
237/// use common_range_tools::{CpCmp,IncDecCpCmp};
238///
239/// struct MyTrait {}
240///
241/// // First: implement CpCmp<T> for your trait.
242/// impl CpCmp<i32> for MyTrait {
243///     fn min(&self) ->i32 { <i32>::MIN }
244///     fn max(&self) ->i32 { <i32>::MAX }
245///     fn min_ref(&self) ->&i32 { &<i32>::MIN }
246///     fn max_ref(&self) ->&i32 { &<i32>::MAX }
247///
248///     fn cp(&self,v: &i32) ->i32 { return v.clone() }
249///
250///     fn lt(&self,a:&i32,b: &i32) ->bool {  return a<b  }
251/// }
252///
253/// // Next: implement IncDecCpCmp<T> for your trait.
254/// impl IncDecCpCmp<i32,i32> for MyTrait {
255///     fn dec(&self, a: &i32, b:&i32) ->Option<i32> {
256///         if *b<=0 { return None}
257///         return a.clone().checked_sub(b.clone());
258///     }
259///     fn inc(&self, a: &i32, b: &i32) -> Option<i32> {
260///         if *b<=0 { return None}
261///         return a.clone().checked_add(b.clone())
262///     }
263///     fn cp_v(&self,v:&i32) ->i32 {
264///         return *v;
265///     }
266/// }
267/// ```
268///
269pub trait IncDecCpCmp<T, V>: CpCmp<T> {
270    /// Should safely increment a by b.  The value should always go up.. if not then it should return None.
271    fn inc(&self, a: &T, b: &V) -> Option<T>;
272
273    /// Should safely decrement a by b.  The value should always go down... if not then it should return None.
274    fn dec(&self, a: &T, b: &V) -> Option<T>;
275
276    fn cp_v(&self, v: &V) -> V;
277
278    /// Returns the raw adjusted start value.
279    ///   - [std::ops::Bound::Unbounded] becomes self.min()
280    ///   - [std::ops::Bound::Included] value is not changed
281    ///   - [std::ops::Bound::Excluded] value is incremented
282    fn rebound_start(&self, start: Bound<&T>, rebound: &V) -> Option<T> {
283        match start {
284            Bound::Included(begin) => Some(self.cp(begin)),
285            Bound::Excluded(begin) => self.inc(begin, rebound),
286            Bound::Unbounded => Some(self.min()),
287        }
288    }
289
290    /// Returns the raw adjusted end value.
291    ///   - [std::ops::Bound::Unbounded] becomes
292    ///   - [std::ops::Bound::Included] value is not changed
293    ///   - [std::ops::Bound::Excluded] value is decremented
294    fn rebound_end(&self, end: Bound<&T>, rebound: &V) -> Option<T> {
295        match end {
296            Bound::Included(end) => Some(self.cp(end)),
297            Bound::Excluded(end) => self.dec(end, rebound),
298            Bound::Unbounded => Some(self.max()),
299        }
300    }
301}
302
303/// **Default values**
304///
305/// Implemenations of this trait drive the internals used for [crate::iter::Intersector].
306pub trait DefaultValues<T, V>: IncDecCpCmp<T, V> {
307    /// Returns the default value use for progressing a begin or end value of a range.
308    fn default_step(&self) -> V;
309
310    /// Returns the value used to adjust a start or end value in the context of [std::ops::Bound].
311    fn default_rebound(&self) -> V;
312
313    /// Returns the default minimum value.
314    fn default_min() -> T;
315
316    /// Returns the default maximum value.
317    fn default_max() -> T;
318}
319
320macro_rules! impl_inc_dec_cp_cmp_trait_i {
321    ($($t:ty),*) => {
322        $(
323            impl CpCmp<$t> for NumberIncDecCpCmp<$t> {
324                fn min(&self) ->$t { self.min }
325                fn max(&self) ->$t { self.max }
326                fn min_ref(&self) ->&$t { &self.min }
327                fn max_ref(&self) ->&$t { &self.max }
328
329                fn cp(&self,v: &$t) ->$t {
330                    return v.clone();
331                }
332
333                fn lt(&self,a:&$t,b: &$t) ->bool {
334                    return a<b;
335                }
336            }
337
338            impl IncDecCpCmp<$t,$t> for NumberIncDecCpCmp<$t> {
339                fn dec(&self, a: &$t, b:&$t) ->Option<$t> {
340                    if *b<=0 { return None}
341                    return a.clone().checked_sub(b.clone());
342                }
343                fn inc(&self, a: &$t, b: &$t) -> Option<$t> {
344                    if *b<=0 { return None}
345                    return a.clone().checked_add(b.clone())
346                }
347                fn cp_v(&self,v: &$t) ->$t {
348                    return *v;
349                }
350            }
351
352            impl DefaultValues<$t,$t> for NumberIncDecCpCmp<$t> {
353                fn default_step(&self) ->$t { return 1}
354                fn default_rebound(&self) ->$t { return 1}
355                fn default_min() ->$t { <$t>::MIN }
356                fn default_max() ->$t { <$t>::MAX }
357            }
358        )*
359    };
360}
361
362macro_rules! impl_inc_dec_cp_cmp_trait_u {
363    ($($t:ty),*) => {
364        $(
365            impl CpCmp<$t> for NumberIncDecCpCmp<$t> {
366                fn min(&self) ->$t { self.min }
367                fn max(&self) ->$t { self.max }
368                fn min_ref(&self) ->&$t { &self.min }
369                fn max_ref(&self) ->&$t { &self.max }
370
371                fn cp(&self,v: &$t) ->$t {
372                    return v.clone();
373                }
374
375                fn lt(&self,a:&$t,b: &$t) ->bool {
376                    return a<b;
377                }
378            }
379            impl IncDecCpCmp<$t,$t> for NumberIncDecCpCmp<$t> {
380                fn dec(&self, a: &$t, b:&$t) ->Option<$t> {
381                    if *b==0 { return None}
382                    return a.clone().checked_sub(b.clone());
383                }
384                fn inc(&self, a: &$t, b: &$t) -> Option<$t> {
385                    if *b==0 { return None}
386                    return a.clone().checked_add(b.clone())
387                }
388                fn cp_v(&self,v: &$t) ->$t {
389                    return *v;
390                }
391            }
392
393            impl DefaultValues<$t,$t> for NumberIncDecCpCmp<$t> {
394                fn default_step(&self) ->$t { return 1}
395                fn default_rebound(&self) ->$t { return 1}
396                fn default_min() ->$t { <$t>::MIN }
397                fn default_max() ->$t { <$t>::MAX }
398            }
399        )*
400    };
401}
402
403macro_rules! impl_inc_dec_cp_cmp_trait_f {
404    ($($t:ty),*) => {
405        $(
406
407
408            impl CpCmp<$t> for NumberIncDecCpCmp<$t> {
409
410                fn min(&self) ->$t { self.min }
411                fn max(&self) ->$t { self.max }
412                fn min_ref(&self) ->&$t { &self.min }
413                fn max_ref(&self) ->&$t { &self.max }
414                fn cp(&self,v: &$t) ->$t {
415                    return v.clone();
416                }
417                fn lt(&self,a:&$t,b: &$t) ->bool {
418                    return a<b;
419                }
420            }
421            impl IncDecCpCmp<$t,$t> for NumberIncDecCpCmp<$t> {
422                fn dec(&self, a: &$t, b:&$t) ->Option<$t> {
423                    let res=a - b;
424                    if res.is_nan() || res >=*a { None } else { Some(res) }
425                }
426                fn inc(&self, a: &$t, b: &$t) -> Option<$t> {
427                    let res=a + b;
428                    if res.is_nan() || res <=*a { None } else { Some(res) }
429                }
430                fn cp_v(&self,v: &$t) ->$t {
431                    return *v;
432                }
433            }
434
435            impl DefaultValues<$t,$t> for NumberIncDecCpCmp<$t> {
436                fn default_step(&self) ->$t { return 1.0}
437                fn default_rebound(&self) ->$t { return 1.0 }
438                fn default_min() ->$t { <$t>::MIN }
439                fn default_max() ->$t { <$t>::MAX }
440            }
441        )*
442    };
443}
444
445impl_inc_dec_cp_cmp_trait_u!(u8, u16, u32, u64, u128, usize);
446impl_inc_dec_cp_cmp_trait_i!(i8, i16, i32, i64, i128, isize);
447impl_inc_dec_cp_cmp_trait_f!(f32, f64);
448
449/// This trait represents how ranges factories are to be implemented.
450pub trait GetBeginEndOption<T, R: GetBeginEnd<T>> {
451    fn factory(&self, opt: Option<(T, T)>) -> Option<R>;
452    fn new_range(&self, src: (T, T)) -> R;
453}
454
455/// This is the factory implemntation of [GetBeginEndOption] for [Mrs].
456#[derive(Copy, Clone)]
457pub struct MrsFactory<T> {
458    _t: PhantomData<T>,
459}
460
461/// This is the factory implementation of [GetBeginEndOption] for [std::ops::RangeInclusive].
462#[derive(Copy, Clone)]
463pub struct RiFactory<T> {
464    _t: PhantomData<T>,
465}
466
467impl<T> RiFactory<T> {
468    pub fn new() -> Self {
469        return Self { _t: PhantomData };
470    }
471}
472
473impl<T> MrsFactory<T> {
474    pub fn new() -> Self {
475        return Self { _t: PhantomData };
476    }
477}
478
479impl<T> GetBeginEndOption<T, Mrs<T>> for MrsFactory<T> {
480    fn new_range(&self, src: (T, T)) -> Mrs<T> {
481        return Mrs::new(src.0, src.1);
482    }
483    fn factory(&self, opt: Option<(T, T)>) -> Option<Mrs<T>> {
484        match opt {
485            Some((a, z)) => Some(Mrs::new(a, z)),
486            None => None,
487        }
488    }
489}
490
491impl<T> GetBeginEndOption<T, RangeInclusive<T>> for RiFactory<T> {
492    fn new_range(&self, src: (T, T)) -> RangeInclusive<T> {
493        return RangeInclusive::new(src.0, src.1);
494    }
495    fn factory(&self, opt: Option<(T, T)>) -> Option<RangeInclusive<T>> {
496        match opt {
497            Some((a, z)) => Some(RangeInclusive::new(a, z)),
498            None => None,
499        }
500    }
501}