Skip to main content

common_range_tools/iter/consolidate/checker/
column.rs

1use std::{cell::RefCell, mem, ops::RangeBounds, rc::Rc};
2pub mod columns;
3
4use crate::{
5    ConsolidateChecker, ConsolidateMrsP, GetBeginEnd, GetBeginEndOption, IncDecCpCmp, Intersector,
6    OverlapIter,
7};
8
9/// Represents a column in an instance of [OverlapIter] in which the [Column] itself is an [Iterator].
10pub struct Column<
11    T,
12    V,
13    R: GetBeginEnd<T>,
14    S: RangeBounds<T>,
15    F: GetBeginEndOption<T, R>,
16    I: Iterator<Item = S>,
17    C: IncDecCpCmp<T, V>,
18> {
19    col: Result<usize, &'static str>,
20    checker: RefCell<ConsolidateChecker<T, V, R, S, F, I, C>>,
21    rows: RefCell<Vec<Rc<ConsolidateMrsP<T, R, S>>>>,
22    err: Result<(), &'static str>,
23}
24
25impl<
26    T,
27    V,
28    R: GetBeginEnd<T>,
29    S: RangeBounds<T>,
30    F: GetBeginEndOption<T, R>,
31    I: Iterator<Item = S>,
32    C: IncDecCpCmp<T, V>,
33> Column<T, V, R, S, F, I, C>
34{
35    fn update_iter<Q: GetBeginEnd<T>, X: GetBeginEndOption<T, Q>>(
36        &mut self,
37        iter: &mut OverlapIter<T, V, C, Q, X>,
38        idx: usize,
39        col: Q,
40    ) -> bool
41    where
42        C: IncDecCpCmp<T, V>,
43    {
44        if let Err(e) = iter.update_column(idx, col) {
45            self.err = Err(e);
46            return false;
47        }
48        return true;
49    }
50
51    fn get_cmp<'r>(&self) -> &'r C {
52        let checker = &*self.checker.borrow();
53        return unsafe { mem::transmute(checker.get_cmp()) };
54    }
55
56    pub fn update_column<Q: GetBeginEnd<T>, X: GetBeginEndOption<T, Q>>(
57        &mut self,
58        last: &Q,
59        iter: &mut OverlapIter<T, V, C, Q, X>,
60        reset: bool,
61    ) -> bool
62    where
63        C: IncDecCpCmp<T, V>,
64    {
65        let col: usize;
66        match &self.col {
67            Ok(idx) => col = *idx,
68            Err(_) => return false,
69        }
70
71        // reset the column error state each time we process a column.
72        self.err = Ok(());
73        let order;
74        let cmp = self.get_cmp();
75        {
76            let checker = self.checker.borrow();
77            order = checker.get_order();
78            if let Some(row) = self.rows.borrow().last() {
79                if reset {
80                    if order.is_beyond(row.as_ref(), last, cmp) {
81                        return false;
82                    }
83                } else {
84                    let (overlap, done) = order.check_position(row.as_ref(), last, cmp);
85
86                    if overlap || done {
87                        // if we get here then we overlap with the current set or we are beyond it!
88                        return false;
89                    }
90                }
91            }
92        }
93
94        loop {
95            let nc = self.checker.borrow_mut().next();
96            if let Some(next) = nc {
97                match next {
98                    Err((msg, row)) => {
99                        self.rows.borrow_mut().clear();
100                        let clone = iter.factory.new_range(cmp.cp_tpl_ref(row.to_tuple_ref()));
101                        self.rows.borrow_mut().push(Rc::new(row));
102                        self.err = Err(msg);
103                        return self.update_iter(iter, col, clone);
104                    }
105                    Ok(row) => {
106                        let rc = Rc::new(row);
107                        let clone = Rc::clone(&rc);
108                        self.rows.borrow_mut().push(rc);
109                        let r = clone.as_ref();
110                        if reset {
111                            if order.is_beyond(r, last, cmp) {
112                                let clone =
113                                    iter.factory.new_range(cmp.cp_tpl_ref(r.to_tuple_ref()));
114                                return self.update_iter(iter, col, clone);
115                            }
116                        } else if order.is_before(r, last, cmp) {
117                            let clone = iter.factory.new_range(cmp.cp_tpl_ref(r.to_tuple_ref()));
118                            return self.update_iter(iter, col, clone);
119                        } else {
120                            let (overlap, done) = order.check_position(r, last, cmp);
121                            if overlap || done {
122                                let clone =
123                                    iter.factory.new_range(cmp.cp_tpl_ref(r.to_tuple_ref()));
124
125                                return self.update_iter(iter, col, clone);
126                            }
127                        }
128                    }
129                }
130            } else {
131                return false;
132            }
133        }
134    }
135
136    pub fn filter_column<Q: GetBeginEnd<T>>(
137        &self,
138        next: &Q,
139    ) -> Result<Vec<Rc<ConsolidateMrsP<T, R, S>>>, &'static str> {
140        if let Err(e) = &self.col {
141            return Err(e);
142        } else if let Err(e) = &self.err {
143            // make sure we can progress on this column instances by clearing the error.
144            return Err(e);
145        }
146        let mut results = Vec::new();
147        let checker = self.checker.borrow();
148
149        let cmp = checker.get_cmp();
150        let order = checker.get_order();
151        let rows = self.rows.replace(Vec::new());
152        for row in rows {
153            let (overlap, done) = order.check_position(row.as_ref(), next, cmp);
154            if overlap {
155                results.push(Rc::clone(&row));
156                self.rows.borrow_mut().push(row);
157            } else if done {
158                self.rows.borrow_mut().push(row);
159            }
160        }
161        return Ok(results);
162    }
163
164    pub fn in_err(&self) -> bool {
165        return self.col.is_err() || self.err.is_err();
166    }
167
168    pub fn get_column(&self) -> Result<usize, &'static str> {
169        let col = self.col?;
170        return Ok(col);
171    }
172
173    pub fn get_rows<'a>(&self) -> &'a Vec<Rc<ConsolidateMrsP<T, R, S>>> {
174        let res = &*self.rows.borrow();
175        return unsafe {
176            mem::transmute::<
177                &'_ Vec<Rc<ConsolidateMrsP<T, R, S>>>,
178                &'a Vec<Rc<ConsolidateMrsP<T, R, S>>>,
179            >(res)
180        };
181    }
182
183    /// Unwraps the current object state into a tuple.  
184    /// The resulting values from the returned tuple can be used to crate a new instance of [Column] with via the [Column::builder].
185    pub fn to_inner(
186        self,
187    ) -> (
188        Result<usize, &'static str>,
189        Vec<Rc<ConsolidateMrsP<T, R, S>>>,
190        ConsolidateChecker<T, V, R, S, F, I, C>,
191    ) {
192        return (self.col, self.rows.into_inner(), self.checker.into_inner());
193    }
194    pub fn new<Q: GetBeginEnd<T>, X: GetBeginEndOption<T, Q>>(
195        isec: &mut Intersector<T, V, C, Q, X>,
196        mut checker: ConsolidateChecker<T, V, R, S, F, I, C>,
197    ) -> Result<Self, Self>
198    where
199        C: IncDecCpCmp<T, V>,
200    {
201        let mut col = Err("checker has no next()");
202        let mut rows = Vec::new();
203
204        if let Some(next) = checker.next() {
205            match next {
206                Ok(r) => {
207                    let rc = Rc::new(r);
208                    let c = Rc::clone(&rc);
209
210                    rows.push(rc);
211                    match isec.add_from_tuple_ref(c.as_ref().to_tuple_ref()) {
212                        Some((idx, _)) => {
213                            col = Ok(idx);
214                            return Ok(Self::builder((col, checker, rows)));
215                        }
216                        None => {
217                            col = Err("Failed to add column from: checker");
218                            return Err(Self::builder((col, checker, rows)));
219                        }
220                    }
221                }
222                Err((e, r)) => {
223                    col = Err(e);
224                    rows.push(Rc::new(r));
225                    return Err(Self::builder((col, checker, rows)));
226                }
227            }
228        } else {
229            return Err(Self::builder((col, checker, rows)));
230        }
231    }
232
233    /// This method alllows construction of a new instance of [Column] bypassing the operations performed by new.
234    pub fn builder(
235        inner: (
236            Result<usize, &'static str>,
237            ConsolidateChecker<T, V, R, S, F, I, C>,
238            Vec<Rc<ConsolidateMrsP<T, R, S>>>,
239        ),
240    ) -> Self {
241        return Self {
242            err: Ok(()),
243            col: inner.0,
244            checker: RefCell::new(inner.1),
245            rows: RefCell::new(inner.2),
246        };
247    }
248}