Skip to main content

common_range_tools/iter/consolidate/checker/column/
columns.rs

1use std::{
2    cell::RefCell,
3    mem,
4    ops::{Add, RangeBounds, RangeInclusive, Sub},
5    rc::Rc,
6};
7
8use crate::{
9    AnyIncDecCpCmp, Column, Consolidate, ConsolidateChecker, ConsolidateMrsP, ConsolidationOrder,
10    CpCmp, DefaultValues, GetBeginEnd, GetBeginEndOption, IncDecCpCmp, Intersector,
11    NumberIncDecCpCmp, OverlapIter, RiFactory,
12};
13
14/// A factory interface for adding [Iterator] instances as [GetBeginEnd] instances for intersectional evaluation via an [OverlapIter].
15pub struct Columns<
16    T,
17    V,
18    I: Iterator<Item = S>,
19    R: GetBeginEnd<T>,
20    S: RangeBounds<T>,
21    C: IncDecCpCmp<T, V>,
22    F: GetBeginEndOption<T, R> + Copy + Clone,
23> {
24    isec: RefCell<Intersector<T, V, C, RangeInclusive<T>, RiFactory<T>>>,
25    factory: F,
26    columns: RefCell<Vec<Column<T, V, R, S, F, I, C>>>,
27    cmp: C,
28    order: ConsolidationOrder,
29    rebound: V,
30}
31
32impl<S: RangeBounds<T>, T: Copy + Clone + PartialOrd, I: Iterator<Item = S>>
33    Columns<T, T, I, RangeInclusive<T>, S, NumberIncDecCpCmp<T>, RiFactory<T>>
34where
35    NumberIncDecCpCmp<T>: DefaultValues<T, T>,
36{
37    pub fn num(order: ConsolidationOrder, step: T, rebound: T, min: T, max: T) -> Self {
38        let cmp = NumberIncDecCpCmp::new(min, max);
39        let factory = RiFactory::new();
40        return Self::new(order, cmp, factory, step, rebound);
41    }
42
43    pub fn num_sr(sr: T) -> Self {
44        let cmp = NumberIncDecCpCmp::defaults();
45        let factory = RiFactory::new();
46        return Self::new(ConsolidationOrder::Forward, cmp, factory, sr, sr);
47    }
48
49    pub fn num_defaults() -> Self {
50        let cmp = NumberIncDecCpCmp::defaults();
51        return Self::num(
52            ConsolidationOrder::Forward,
53            cmp.default_step(),
54            cmp.default_step(),
55            cmp.min(),
56            cmp.max(),
57        );
58    }
59
60    pub fn num_defaults_rev() -> Self {
61        let cmp = NumberIncDecCpCmp::defaults();
62        return Self::num(
63            ConsolidationOrder::Reverse,
64            cmp.default_step(),
65            cmp.default_step(),
66            cmp.min(),
67            cmp.max(),
68        );
69    }
70}
71
72impl<S: RangeBounds<T>, T, V, I: Iterator<Item = S>>
73    Columns<T, V, I, RangeInclusive<T>, S, AnyIncDecCpCmp<T>, RiFactory<T>>
74where
75    V: Copy,
76    T: PartialOrd + Copy + Add<V, Output = T> + Sub<V, Output = T>,
77{
78    pub fn any(order: ConsolidationOrder, cmp: AnyIncDecCpCmp<T>, step: V, rebound: V) -> Self {
79        return Self::new(order, cmp, RiFactory::new(), step, rebound);
80    }
81}
82impl<
83    T,
84    V,
85    I: Iterator<Item = S>,
86    R: GetBeginEnd<T>,
87    S: RangeBounds<T>,
88    C: IncDecCpCmp<T, V> + Copy + Clone,
89    F: GetBeginEndOption<T, R> + Copy + Clone,
90> Columns<T, V, I, R, S, C, F>
91{
92    /// Creates a new instance of the [Columns] factory which can converted into an [Iterator] of [ColumnsIter].
93    pub fn new(order: ConsolidationOrder, cmp: C, factory: F, step: V, rebound: V) -> Self {
94        let rb = cmp.cp_v(&rebound);
95        return Self {
96            isec: RefCell::new(Intersector::new(
97                Vec::new(),
98                step,
99                rebound,
100                cmp,
101                RiFactory::new(),
102            )),
103            factory,
104            columns: RefCell::new(Vec::new()),
105            cmp,
106            order,
107            rebound: rb,
108        };
109    }
110
111    /// Tries to add the column to the set of columns.
112    ///  - Ok([usize]) is the id of the column
113    ///  - Err([Column]) is the column that failed to be added.
114    pub fn add_column(&self, iter: I) -> Result<usize, Column<T, V, R, S, F, I, C>> {
115        let con = Consolidate::new(iter, self.cmp, self.factory, self.cmp.cp_v(&self.rebound));
116        let checker = ConsolidateChecker::new(self.order, con);
117        match Column::new(&mut *self.isec.borrow_mut(), checker) {
118            Ok(res) => {
119                let idx = res.get_column();
120                match idx {
121                    Ok(id) => {
122                        self.columns.borrow_mut().push(res);
123                        return Ok(id);
124                    }
125                    Err(_) => {
126                        return Err(res);
127                    }
128                }
129            }
130            Err(res) => Err(res),
131        }
132    }
133}
134
135impl<
136    T,
137    V,
138    I: Iterator<Item = S>,
139    R: GetBeginEnd<T>,
140    S: RangeBounds<T>,
141    C: IncDecCpCmp<T, V> + Copy + Clone,
142    F: GetBeginEndOption<T, R> + Copy + Clone,
143> IntoIterator for Columns<T, V, I, R, S, C, F>
144{
145    type Item = (
146        RangeInclusive<T>,
147        Result<(), &'static str>,
148        Vec<Result<Vec<Rc<ConsolidateMrsP<T, R, S>>>, &'static str>>,
149    );
150
151    type IntoIter = ColumnsIter<T, V, I, R, S, C, F>;
152
153    /// Converts [Columns] into an instance of [ColumnsIter].
154    fn into_iter(self) -> Self::IntoIter {
155        return ColumnsIter::new(
156            self.isec.into_inner().into_iter(),
157            self.columns.into_inner(),
158            self.order,
159            true,
160        );
161    }
162}
163
164/// Acts as an [Iterator] over [Column] instances finding the intersections via an internal [OverlapIter].
165pub struct ColumnsIter<
166    T,
167    V,
168    I: Iterator<Item = S>,
169    R: GetBeginEnd<T>,
170    S: RangeBounds<T>,
171    C: IncDecCpCmp<T, V>,
172    F: GetBeginEndOption<T, R> + Copy + Clone,
173> {
174    iter: RefCell<OverlapIter<T, V, C, RangeInclusive<T>, RiFactory<T>>>,
175    cols: Vec<Column<T, V, R, S, F, I, C>>,
176    order: ConsolidationOrder,
177    needs_init: bool,
178}
179impl<
180    T,
181    V,
182    I: Iterator<Item = S>,
183    R: GetBeginEnd<T>,
184    S: RangeBounds<T>,
185    C: IncDecCpCmp<T, V>,
186    F: GetBeginEndOption<T, R> + Copy + Clone,
187> ColumnsIter<T, V, I, R, S, C, F>
188{
189    /// Constructs a new instance of [ColumnsIter].
190    pub fn new(
191        iter: OverlapIter<T, V, C, RangeInclusive<T>, RiFactory<T>>,
192        cols: Vec<Column<T, V, R, S, F, I, C>>,
193        order: ConsolidationOrder,
194        needs_init: bool,
195    ) -> Self {
196        Self {
197            iter: RefCell::new(iter),
198            cols,
199            order,
200            needs_init,
201        }
202    }
203
204    pub fn get_column<'a>(&self, idx: usize) -> Option<&'a Column<T, V, R, S, F, I, C>> {
205        let res = self.cols.get(idx);
206
207        return unsafe {
208            mem::transmute::<
209                Option<&'_ Column<T, V, R, S, F, I, C>>,
210                Option<&'a Column<T, V, R, S, F, I, C>>,
211            >(res)
212        };
213    }
214
215    /// Converts self to a tuple, whos contents can be used to construct a new instance of [Columns].
216    pub fn into_inner(
217        self,
218    ) -> (
219        OverlapIter<T, V, C, RangeInclusive<T>, RiFactory<T>>,
220        Vec<Column<T, V, R, S, F, I, C>>,
221        ConsolidationOrder,
222        bool,
223    ) {
224        return (
225            self.iter.into_inner(),
226            self.cols,
227            self.order,
228            self.needs_init,
229        );
230    }
231
232    /// Returns the state of the next,last position relative to the direction.
233    pub fn next_last<'r>(&self) -> (Option<&'r RangeInclusive<T>>, Option<&'r RangeInclusive<T>>) {
234        let iter = &*self.iter.borrow();
235        let (last, next);
236        match &self.order {
237            ConsolidationOrder::Forward => (next, last) = iter.ln(),
238            ConsolidationOrder::Reverse => (next, last) = iter.lb(),
239        }
240
241        return unsafe {
242            mem::transmute::<
243                (Option<&'_ RangeInclusive<T>>, Option<&'_ RangeInclusive<T>>),
244                (Option<&'r RangeInclusive<T>>, Option<&'r RangeInclusive<T>>),
245            >((next, last))
246        };
247    }
248}
249
250impl<
251    T,
252    V,
253    I: Iterator<Item = S>,
254    R: GetBeginEnd<T>,
255    S: RangeBounds<T>,
256    C: IncDecCpCmp<T, V>,
257    F: GetBeginEndOption<T, R> + Copy + Clone,
258> Iterator for ColumnsIter<T, V, I, R, S, C, F>
259{
260    type Item = (
261        RangeInclusive<T>,
262        Result<(), &'static str>,
263        Vec<Result<Vec<Rc<ConsolidateMrsP<T, R, S>>>, &'static str>>,
264    );
265
266    fn next(&mut self) -> Option<Self::Item> {
267        if self.needs_init {
268            let next;
269            // if we got here.. then the instance requires being initalized.
270            self.needs_init = false;
271            match &self.order {
272                ConsolidationOrder::Forward => next = self.iter.borrow_mut().next(),
273                ConsolidationOrder::Reverse => next = self.iter.borrow_mut().next_back(),
274            }
275            if next.is_none() {
276                return None;
277            }
278
279            let filter = next.unwrap();
280            let mut cols = Vec::new();
281            let mut err = Ok(());
282            for col in &mut self.cols {
283                cols.push(col.filter_column(&filter));
284                if col.in_err() {
285                    err = Err("Problem in one ore more Columns")
286                }
287            }
288            return Some((filter, err, cols));
289        }
290
291        let (next, last) = self.next_last();
292        let mut redo = false;
293        let n;
294
295        {
296            let iter = &mut *self.iter.borrow_mut();
297            if let Some(r) = next {
298                for col in &mut self.cols {
299                    if col.update_column(r, iter, false) {
300                        redo = true;
301                    }
302                }
303            } else if let Some(r) = last {
304                redo = true;
305                for col in &mut self.cols {
306                    col.update_column(r, iter, true);
307                }
308            } else {
309                return None;
310            }
311            if redo {
312                match &self.order {
313                    ConsolidationOrder::Forward => n = iter.recompute_next(),
314                    ConsolidationOrder::Reverse => n = iter.recompute_back(),
315                }
316            } else {
317                match &self.order {
318                    ConsolidationOrder::Forward => n = iter.next(),
319                    ConsolidationOrder::Reverse => n = iter.next_back(),
320                }
321            }
322        }
323
324        let mut cols = Vec::new();
325        if n.is_none() {
326            return None;
327        }
328        let filter = n.unwrap();
329        let mut err = Ok(());
330        for col in &mut self.cols {
331            cols.push(col.filter_column(&filter));
332            if col.in_err() {
333                err = Err("Problem in one ore more Columns")
334            }
335        }
336
337        return Some((filter, err, cols));
338    }
339}