tabled/settings/object/
mod.rs

1//! This module contains a list of primitives that implement a [`Object`] trait.\
2//! They help to locate a necessary segment on a [`Table`].
3//!
4//! # Example
5//!
6//! ```
7//! use tabled::{
8//!     settings::{
9//!         object::{Columns, Object, Rows},
10//!         Alignment,
11//!     },
12//!     assert::assert_table,
13//!     Table,
14//! };
15//!
16//! let data = [
17//!     [1, 2, 3, 4, 5],
18//!     [10, 20, 30, 40, 50],
19//!     [100, 200, 300, 400, 500],
20//! ];
21//!
22//! let mut table = Table::new(data);
23//! table.modify(Rows::first().not(Columns::first()), Alignment::right());
24//!
25//! assert_table!(
26//!     table,
27//!     "+-----+-----+-----+-----+-----+"
28//!     "| 0   |   1 |   2 |   3 |   4 |"
29//!     "+-----+-----+-----+-----+-----+"
30//!     "| 1   | 2   | 3   | 4   | 5   |"
31//!     "+-----+-----+-----+-----+-----+"
32//!     "| 10  | 20  | 30  | 40  | 50  |"
33//!     "+-----+-----+-----+-----+-----+"
34//!     "| 100 | 200 | 300 | 400 | 500 |"
35//!     "+-----+-----+-----+-----+-----+"
36//! );
37//! ```
38//!
39//! [`Table`]: crate::Table
40
41mod cell;
42mod columns;
43mod frame;
44mod iterator;
45mod rows;
46mod segment;
47
48pub(crate) mod util;
49
50use std::{collections::HashSet, marker::PhantomData};
51
52use self::segment::SectorCellsIter;
53
54use crate::{
55    grid::config::{Entity, EntityIterator},
56    grid::records::{ExactRecords, Records},
57};
58
59pub use cell::{Cell, EntityOnce};
60pub use columns::{Column, Columns, ColumnsIter, FirstColumn, LastColumn, LastColumnOffset};
61pub use frame::{Frame, FrameIter};
62pub use iterator::{
63    FilterObject, FilterObjectIter, ObjectIterator, SkipObject, SkipObjectIter, StepByObject,
64    StepByObjectIter,
65};
66use papergrid::config::Position;
67pub use rows::{FirstRow, LastRow, LastRowOffset, Row, Rows, RowsIter};
68pub use segment::{SectorIter, Segment, SegmentAll};
69
70/// Object helps to locate a necessary part of a [`Table`].
71///
72/// [`Table`]: crate::Table
73pub trait Object<R> {
74    /// An [`Iterator`] which returns a list of cells.
75    type Iter: Iterator<Item = Entity>;
76
77    /// Cells returns a set of coordinates of cells.
78    fn cells(&self, records: &R) -> Self::Iter;
79
80    /// Combines cells.
81    /// It doesn't repeat cells.
82    fn and<O>(self, rhs: O) -> UnionCombination<Self, O, R>
83    where
84        Self: Sized,
85    {
86        UnionCombination::new(self, rhs)
87    }
88
89    /// Excludes rhs cells from this cells.
90    fn not<O>(self, rhs: O) -> DiffCombination<Self, O, R>
91    where
92        Self: Sized,
93    {
94        DiffCombination::new(self, rhs)
95    }
96
97    /// Returns cells which are present in both [`Object`]s only.
98    fn intersect<O>(self, rhs: O) -> IntersectionCombination<Self, O, R>
99    where
100        Self: Sized,
101    {
102        IntersectionCombination::new(self, rhs)
103    }
104
105    /// Returns cells which are not present in target [`Object`].
106    fn inverse(self) -> InversionCombination<Self, R>
107    where
108        Self: Sized,
109    {
110        InversionCombination::new(self)
111    }
112}
113
114/// Combination struct used for chaining [`Object`]'s.
115///
116/// Combines 2 sets of cells into one.
117///
118/// Duplicates are removed from the output set.
119#[derive(Debug)]
120pub struct UnionCombination<L, R, I> {
121    lhs: L,
122    rhs: R,
123    _records: PhantomData<I>,
124}
125
126impl<L, R, I> UnionCombination<L, R, I> {
127    fn new(lhs: L, rhs: R) -> Self {
128        Self {
129            lhs,
130            rhs,
131            _records: PhantomData,
132        }
133    }
134}
135
136impl<I, L, R> Object<I> for UnionCombination<L, R, I>
137where
138    L: Object<I>,
139    R: Object<I>,
140    I: Records + ExactRecords,
141{
142    type Iter = UnionIter<L::Iter, R::Iter>;
143
144    fn cells(&self, records: &I) -> Self::Iter {
145        let lhs = self.lhs.cells(records);
146        let rhs = self.rhs.cells(records);
147
148        UnionIter::new(lhs, rhs, records.count_rows(), records.count_columns())
149    }
150}
151
152/// Difference struct used for chaining [`Object`]'s.
153///
154/// Returns cells from 1st set with removed ones from the 2nd set.
155#[derive(Debug)]
156pub struct DiffCombination<L, R, I> {
157    lhs: L,
158    rhs: R,
159    _records: PhantomData<I>,
160}
161
162impl<L, R, I> DiffCombination<L, R, I> {
163    fn new(lhs: L, rhs: R) -> Self {
164        Self {
165            lhs,
166            rhs,
167            _records: PhantomData,
168        }
169    }
170}
171
172impl<I, L, R> Object<I> for DiffCombination<L, R, I>
173where
174    L: Object<I>,
175    R: Object<I>,
176    I: Records + ExactRecords,
177{
178    type Iter = DiffIter<L::Iter>;
179
180    fn cells(&self, records: &I) -> Self::Iter {
181        let lhs = self.lhs.cells(records);
182        let rhs = self.rhs.cells(records);
183
184        DiffIter::new(lhs, rhs, records.count_rows(), records.count_columns())
185    }
186}
187
188/// Intersection struct used for chaining [`Object`]'s.
189///
190/// Returns cells which are present in 2 sets.
191/// But not in one of them
192#[derive(Debug)]
193pub struct IntersectionCombination<L, R, I> {
194    lhs: L,
195    rhs: R,
196    _records: PhantomData<I>,
197}
198
199impl<L, R, I> IntersectionCombination<L, R, I> {
200    fn new(lhs: L, rhs: R) -> Self {
201        Self {
202            lhs,
203            rhs,
204            _records: PhantomData,
205        }
206    }
207}
208
209impl<I, L, R> Object<I> for IntersectionCombination<L, R, I>
210where
211    L: Object<I>,
212    R: Object<I>,
213    I: Records + ExactRecords,
214{
215    type Iter = IntersectIter<L::Iter>;
216
217    fn cells(&self, records: &I) -> Self::Iter {
218        let lhs = self.lhs.cells(records);
219        let rhs = self.rhs.cells(records);
220
221        IntersectIter::new(lhs, rhs, records.count_rows(), records.count_columns())
222    }
223}
224
225/// Inversion struct used for chaining [`Object`]'s.
226///
227/// Returns cells which are present in 2 sets.
228/// But not in one of them
229#[derive(Debug)]
230pub struct InversionCombination<O, I> {
231    obj: O,
232    _records: PhantomData<I>,
233}
234
235impl<O, I> InversionCombination<O, I> {
236    fn new(obj: O) -> Self {
237        Self {
238            obj,
239            _records: PhantomData,
240        }
241    }
242}
243
244impl<I, O> Object<I> for InversionCombination<O, I>
245where
246    O: Object<I>,
247    I: Records + ExactRecords,
248{
249    type Iter = InversionIter;
250
251    fn cells(&self, records: &I) -> Self::Iter {
252        let obj = self.obj.cells(records);
253
254        InversionIter::new(obj, records.count_rows(), records.count_columns())
255    }
256}
257
258/// An [`Iterator`] which goes over a combination [`Object::Iter`].
259#[derive(Debug)]
260pub struct UnionIter<L, R> {
261    lhs: Option<L>,
262    rhs: R,
263    seen: HashSet<Position>,
264    current: Option<EntityIterator>,
265    count_rows: usize,
266    count_cols: usize,
267}
268
269impl<L, R> UnionIter<L, R>
270where
271    L: Iterator<Item = Entity>,
272    R: Iterator<Item = Entity>,
273{
274    fn new(lhs: L, rhs: R, count_rows: usize, count_cols: usize) -> Self {
275        let size = match lhs.size_hint() {
276            (s1, Some(s2)) if s1 == s2 => s1,
277            _ => 0,
278        };
279
280        Self {
281            lhs: Some(lhs),
282            rhs,
283            seen: HashSet::with_capacity(size),
284            current: None,
285            count_rows,
286            count_cols,
287        }
288    }
289}
290
291impl<L, R> Iterator for UnionIter<L, R>
292where
293    L: Iterator<Item = Entity>,
294    R: Iterator<Item = Entity>,
295{
296    type Item = Entity;
297
298    fn next(&mut self) -> Option<Self::Item> {
299        if let Some(iter) = self.current.as_mut() {
300            for p in iter.by_ref() {
301                if self.lhs.is_none() && self.seen.contains(&p) {
302                    continue;
303                }
304
305                let _ = self.seen.insert(p);
306
307                return Some(p.into());
308            }
309        }
310
311        if let Some(lhs) = self.lhs.as_mut() {
312            for entity in lhs.by_ref() {
313                let mut iter = entity.iter(self.count_rows, self.count_cols);
314                if let Some(p) = iter.by_ref().next() {
315                    let _ = self.seen.insert(p);
316                    self.current = Some(iter);
317
318                    return Some(p.into());
319                }
320            }
321
322            self.lhs = None;
323        }
324
325        for entity in self.rhs.by_ref() {
326            let mut iter = entity.iter(self.count_rows, self.count_cols);
327
328            for p in iter.by_ref() {
329                if !self.seen.contains(&p) {
330                    let _ = self.seen.insert(p);
331                    self.current = Some(iter);
332
333                    return Some(p.into());
334                }
335            }
336        }
337
338        None
339    }
340}
341
342/// An [`Iterator`] which goes over only cells which are present in first [`Object::Iter`] but not second.
343#[derive(Debug)]
344pub struct DiffIter<L> {
345    lhs: L,
346    seen: HashSet<Position>,
347    count_rows: usize,
348    count_cols: usize,
349    current: Option<EntityIterator>,
350}
351
352impl<L> DiffIter<L>
353where
354    L: Iterator<Item = Entity>,
355{
356    fn new<R>(lhs: L, rhs: R, count_rows: usize, count_cols: usize) -> Self
357    where
358        R: Iterator<Item = Entity>,
359    {
360        let size = match rhs.size_hint() {
361            (s1, Some(s2)) if s1 == s2 => s1,
362            _ => 0,
363        };
364
365        let mut seen = HashSet::with_capacity(size);
366        for entity in rhs {
367            seen.extend(entity.iter(count_rows, count_cols));
368        }
369
370        Self {
371            lhs,
372            seen,
373            count_rows,
374            count_cols,
375            current: None,
376        }
377    }
378}
379
380impl<L> Iterator for DiffIter<L>
381where
382    L: Iterator<Item = Entity>,
383{
384    type Item = Entity;
385
386    fn next(&mut self) -> Option<Self::Item> {
387        if let Some(iter) = self.current.as_mut() {
388            for p in iter.by_ref() {
389                if !self.seen.contains(&p) {
390                    return Some(p.into());
391                }
392            }
393        }
394
395        for entity in self.lhs.by_ref() {
396            let mut iter = entity.iter(self.count_rows, self.count_cols);
397
398            for p in iter.by_ref() {
399                if !self.seen.contains(&p) {
400                    self.current = Some(iter);
401                    return Some(p.into());
402                }
403            }
404        }
405
406        None
407    }
408}
409
410/// An [`Iterator`] which goes goes over cells which are present in both [`Object::Iter`]ators.
411#[derive(Debug)]
412pub struct IntersectIter<L> {
413    lhs: L,
414    seen: HashSet<Position>,
415    count_rows: usize,
416    count_cols: usize,
417    current: Option<EntityIterator>,
418}
419
420impl<L> IntersectIter<L>
421where
422    L: Iterator<Item = Entity>,
423{
424    fn new<R>(lhs: L, rhs: R, count_rows: usize, count_cols: usize) -> Self
425    where
426        R: Iterator<Item = Entity>,
427    {
428        let size = match rhs.size_hint() {
429            (s1, Some(s2)) if s1 == s2 => s1,
430            _ => 0,
431        };
432
433        let mut seen = HashSet::with_capacity(size);
434        for entity in rhs {
435            seen.extend(entity.iter(count_rows, count_cols));
436        }
437
438        Self {
439            lhs,
440            seen,
441            count_rows,
442            count_cols,
443            current: None,
444        }
445    }
446}
447
448impl<L> Iterator for IntersectIter<L>
449where
450    L: Iterator<Item = Entity>,
451{
452    type Item = Entity;
453
454    fn next(&mut self) -> Option<Self::Item> {
455        if let Some(iter) = self.current.as_mut() {
456            for p in iter.by_ref() {
457                if self.seen.contains(&p) {
458                    return Some(p.into());
459                }
460            }
461        }
462
463        for entity in self.lhs.by_ref() {
464            let mut iter = entity.iter(self.count_rows, self.count_cols);
465
466            for p in iter.by_ref() {
467                if self.seen.contains(&p) {
468                    self.current = Some(iter);
469                    return Some(p.into());
470                }
471            }
472        }
473
474        None
475    }
476}
477
478/// An [`Iterator`] which goes goes over cells which are not present an [`Object::Iter`]ator.
479#[derive(Debug)]
480pub struct InversionIter {
481    all: SectorCellsIter,
482    seen: HashSet<Position>,
483}
484
485impl InversionIter {
486    fn new<O>(obj: O, count_rows: usize, count_columns: usize) -> Self
487    where
488        O: Iterator<Item = Entity>,
489    {
490        let size = match obj.size_hint() {
491            (s1, Some(s2)) if s1 == s2 => s1,
492            _ => 0,
493        };
494
495        let mut seen = HashSet::with_capacity(size);
496        for entity in obj {
497            seen.extend(entity.iter(count_rows, count_columns));
498        }
499
500        let all = SectorCellsIter::new(0, count_rows, 0, count_columns);
501
502        Self { all, seen }
503    }
504}
505
506impl Iterator for InversionIter {
507    type Item = Entity;
508
509    fn next(&mut self) -> Option<Self::Item> {
510        for p in self.all.by_ref() {
511            if !self.seen.contains(&p) {
512                return Some(p.into());
513            }
514        }
515
516        None
517    }
518}
519
520#[cfg(test)]
521mod tests {
522    use crate::grid::records::vec_records::VecRecords;
523
524    use super::*;
525
526    #[test]
527    fn cell_test() {
528        assert_eq!(vec_cells((0, 0), 2, 3), [Entity::Cell(0, 0)]);
529        assert_eq!(vec_cells((1, 1), 2, 3), [Entity::Cell(1, 1)]);
530        assert_eq!(vec_cells((1, 1), 0, 0), [Entity::Cell(1, 1)]);
531        assert_eq!(vec_cells((1, 100), 2, 3), [Entity::Cell(1, 100)]);
532        assert_eq!(vec_cells((100, 1), 2, 3), [Entity::Cell(100, 1)]);
533    }
534
535    #[test]
536    fn columns_test() {
537        assert_eq!(
538            vec_cells(Columns::new(..), 2, 3),
539            [Entity::Column(0), Entity::Column(1), Entity::Column(2)]
540        );
541        assert_eq!(
542            vec_cells(Columns::new(1..), 2, 3),
543            [Entity::Column(1), Entity::Column(2)]
544        );
545        assert_eq!(vec_cells(Columns::new(2..), 2, 3), [Entity::Column(2)]);
546        assert_eq!(vec_cells(Columns::new(3..), 2, 3), []);
547        assert_eq!(vec_cells(Columns::new(3..), 0, 0), []);
548        assert_eq!(vec_cells(Columns::new(0..1), 2, 3), [Entity::Column(0)]);
549        assert_eq!(vec_cells(Columns::new(1..2), 2, 3), [Entity::Column(1)]);
550        assert_eq!(vec_cells(Columns::new(2..3), 2, 3), [Entity::Column(2)]);
551        assert_eq!(vec_cells(Columns::new(..), 0, 0), []);
552        assert_eq!(vec_cells(Columns::new(..), 2, 0), []);
553        assert_eq!(vec_cells(Columns::new(..), 0, 3), []);
554    }
555
556    #[test]
557    fn first_column_test() {
558        assert_eq!(vec_cells(Columns::first(), 5, 2), [Entity::Column(0)]);
559        assert_eq!(vec_cells(Columns::first(), 0, 0), []);
560        assert_eq!(vec_cells(Columns::first(), 10, 0), []);
561        assert_eq!(vec_cells(Columns::first(), 0, 10), []);
562    }
563
564    #[test]
565    fn last_column_test() {
566        assert_eq!(vec_cells(Columns::last(), 5, 2), [Entity::Column(1)]);
567        assert_eq!(vec_cells(Columns::last(), 5, 29), [Entity::Column(28)]);
568        assert_eq!(vec_cells(Columns::last(), 0, 0), []);
569        assert_eq!(vec_cells(Columns::last(), 10, 0), []);
570        assert_eq!(vec_cells(Columns::last(), 0, 10), []);
571    }
572
573    #[test]
574    fn last_column_sub_test() {
575        assert_eq!(vec_cells(Columns::last(), 5, 2), [Entity::Column(1)]);
576        assert_eq!(vec_cells(Columns::last() - 0, 5, 2), [Entity::Column(1)]);
577        assert_eq!(vec_cells(Columns::last() - 1, 5, 2), [Entity::Column(0)]);
578        assert_eq!(vec_cells(Columns::last() - 2, 5, 2), []);
579        assert_eq!(vec_cells(Columns::last() - 100, 5, 2), []);
580    }
581
582    #[test]
583    fn first_column_add_test() {
584        assert_eq!(vec_cells(Columns::first(), 5, 2), [Entity::Column(0)]);
585        assert_eq!(vec_cells(Columns::first() + 0, 5, 2), [Entity::Column(0)]);
586        assert_eq!(vec_cells(Columns::first() + 1, 5, 2), [Entity::Column(1)]);
587        assert_eq!(vec_cells(Columns::first() + 2, 5, 2), [Entity::Column(2)]);
588        assert_eq!(
589            vec_cells(Columns::first() + 100, 5, 2),
590            [Entity::Column(100)]
591        );
592    }
593
594    #[test]
595    fn rows_test() {
596        assert_eq!(
597            vec_cells(Rows::new(..), 2, 3),
598            [Entity::Row(0), Entity::Row(1)]
599        );
600        assert_eq!(vec_cells(Rows::new(1..), 2, 3), [Entity::Row(1)]);
601        assert_eq!(vec_cells(Rows::new(2..), 2, 3), []);
602        assert_eq!(vec_cells(Rows::new(2..), 0, 0), []);
603        assert_eq!(vec_cells(Rows::new(0..1), 2, 3), [Entity::Row(0)],);
604        assert_eq!(vec_cells(Rows::new(1..2), 2, 3), [Entity::Row(1)],);
605        assert_eq!(vec_cells(Rows::new(..), 0, 0), []);
606        assert_eq!(vec_cells(Rows::new(..), 0, 3), []);
607        assert_eq!(
608            vec_cells(Rows::new(..), 2, 0),
609            [Entity::Row(0), Entity::Row(1)]
610        );
611    }
612
613    #[test]
614    fn last_row_test() {
615        assert_eq!(vec_cells(Rows::last(), 5, 2), [Entity::Row(4)]);
616        assert_eq!(vec_cells(Rows::last(), 100, 2), [Entity::Row(99)]);
617        assert_eq!(vec_cells(Rows::last(), 0, 0), []);
618        assert_eq!(vec_cells(Rows::last(), 5, 0), []);
619        assert_eq!(vec_cells(Rows::last(), 0, 2), []);
620    }
621
622    #[test]
623    fn first_row_test() {
624        assert_eq!(vec_cells(Rows::first(), 5, 2), [Entity::Row(0)]);
625        assert_eq!(vec_cells(Rows::first(), 100, 2), [Entity::Row(0)]);
626        assert_eq!(vec_cells(Rows::first(), 0, 0), []);
627        assert_eq!(vec_cells(Rows::first(), 5, 0), []);
628        assert_eq!(vec_cells(Rows::first(), 0, 2), []);
629    }
630
631    #[test]
632    fn last_row_sub_test() {
633        assert_eq!(vec_cells(Rows::last(), 5, 2), [Entity::Row(4)]);
634        assert_eq!(vec_cells(Rows::last() - 0, 5, 2), [Entity::Row(4)]);
635        assert_eq!(vec_cells(Rows::last() - 1, 5, 2), [Entity::Row(3)]);
636        assert_eq!(vec_cells(Rows::last() - 2, 5, 2), [Entity::Row(2)]);
637        assert_eq!(vec_cells(Rows::last() - 3, 5, 2), [Entity::Row(1)]);
638        assert_eq!(vec_cells(Rows::last() - 4, 5, 2), [Entity::Row(0)]);
639        assert_eq!(vec_cells(Rows::last() - 5, 5, 2), []);
640        assert_eq!(vec_cells(Rows::last() - 100, 5, 2), []);
641        assert_eq!(vec_cells(Rows::last() - 1, 0, 0), []);
642        assert_eq!(vec_cells(Rows::last() - 1, 5, 0), []);
643        assert_eq!(vec_cells(Rows::last() - 1, 0, 2), []);
644    }
645
646    #[test]
647    fn first_row_add_test() {
648        assert_eq!(vec_cells(Rows::first(), 5, 2), [Entity::Row(0)]);
649        assert_eq!(vec_cells(Rows::first() + 0, 5, 2), [Entity::Row(0)]);
650        assert_eq!(vec_cells(Rows::first() + 1, 5, 2), [Entity::Row(1)]);
651        assert_eq!(vec_cells(Rows::first() + 2, 5, 2), [Entity::Row(2)]);
652        assert_eq!(vec_cells(Rows::first() + 3, 5, 2), [Entity::Row(3)]);
653        assert_eq!(vec_cells(Rows::first() + 4, 5, 2), [Entity::Row(4)]);
654        assert_eq!(vec_cells(Rows::first() + 5, 5, 2), [Entity::Row(5)]);
655        assert_eq!(vec_cells(Rows::first() + 100, 5, 2), [Entity::Row(100)]);
656        assert_eq!(vec_cells(Rows::first() + 1, 0, 0), [Entity::Row(1)]);
657        assert_eq!(vec_cells(Rows::first() + 1, 5, 0), [Entity::Row(1)]);
658        assert_eq!(vec_cells(Rows::first() + 1, 0, 2), [Entity::Row(1)]);
659    }
660
661    #[test]
662    fn frame_test() {
663        assert_eq!(
664            vec_cells(Frame, 2, 3),
665            [
666                Entity::Cell(0, 0),
667                Entity::Cell(0, 1),
668                Entity::Cell(0, 2),
669                Entity::Cell(1, 0),
670                Entity::Cell(1, 1),
671                Entity::Cell(1, 2)
672            ]
673        );
674        assert_eq!(vec_cells(Frame, 0, 0), []);
675        assert_eq!(vec_cells(Frame, 2, 0), []);
676        assert_eq!(vec_cells(Frame, 0, 2), []);
677    }
678
679    #[test]
680    fn segment_test() {
681        assert_eq!(
682            vec_cells(Segment::new(.., ..), 2, 3),
683            [
684                Entity::Cell(0, 0),
685                Entity::Cell(0, 1),
686                Entity::Cell(0, 2),
687                Entity::Cell(1, 0),
688                Entity::Cell(1, 1),
689                Entity::Cell(1, 2)
690            ]
691        );
692        assert_eq!(
693            vec_cells(Segment::new(1.., ..), 2, 3),
694            [Entity::Cell(1, 0), Entity::Cell(1, 1), Entity::Cell(1, 2)]
695        );
696        assert_eq!(vec_cells(Segment::new(2.., ..), 2, 3), []);
697
698        assert_eq!(
699            vec_cells(Segment::new(.., 1..), 2, 3),
700            [
701                Entity::Cell(0, 1),
702                Entity::Cell(0, 2),
703                Entity::Cell(1, 1),
704                Entity::Cell(1, 2)
705            ]
706        );
707        assert_eq!(
708            vec_cells(Segment::new(.., 2..), 2, 3),
709            [Entity::Cell(0, 2), Entity::Cell(1, 2)]
710        );
711        assert_eq!(vec_cells(Segment::new(.., 3..), 2, 3), []);
712
713        assert_eq!(
714            vec_cells(Segment::new(1.., 1..), 2, 3),
715            [Entity::Cell(1, 1), Entity::Cell(1, 2)]
716        );
717        assert_eq!(
718            vec_cells(Segment::new(1..2, 1..2), 2, 3),
719            [Entity::Cell(1, 1)]
720        );
721
722        assert_eq!(vec_cells(Segment::new(5.., 5..), 2, 3), []);
723    }
724
725    #[test]
726    fn object_and_test() {
727        assert_eq!(
728            vec_cells(Cell::new(0, 0).and(Cell::new(0, 0)), 2, 3),
729            [Entity::Cell(0, 0)]
730        );
731        assert_eq!(
732            vec_cells(Cell::new(0, 0).and(Cell::new(1, 2)), 2, 3),
733            [Entity::Cell(0, 0), Entity::Cell(1, 2)]
734        );
735        assert_eq!(vec_cells(Cell::new(0, 0).and(Cell::new(1, 2)), 0, 0), []);
736    }
737
738    #[test]
739    fn object_not_test() {
740        assert_eq!(vec_cells(Rows::first().not(Cell::new(0, 0)), 0, 0), []);
741        assert_eq!(vec_cells(Cell::new(0, 0).not(Cell::new(0, 0)), 2, 3), []);
742        assert_eq!(
743            vec_cells(Rows::first().not(Cell::new(0, 0)), 2, 3),
744            [Entity::Cell(0, 1), Entity::Cell(0, 2)]
745        );
746        assert_eq!(
747            vec_cells(Columns::one(1).not(Rows::one(1)), 3, 3),
748            [Entity::Cell(0, 1), Entity::Cell(2, 1)]
749        );
750        assert_eq!(
751            vec_cells(Rows::one(1).not(Columns::one(1)), 3, 3),
752            [Entity::Cell(1, 0), Entity::Cell(1, 2)]
753        );
754    }
755
756    #[test]
757    fn object_intersect_test() {
758        assert_eq!(
759            vec_cells(Rows::first().intersect(Cell::new(0, 0)), 0, 0),
760            []
761        );
762        assert_eq!(
763            vec_cells(Segment::all().intersect(Rows::one(1)), 2, 3),
764            [Entity::Cell(1, 0), Entity::Cell(1, 1), Entity::Cell(1, 2)]
765        );
766        assert_eq!(
767            vec_cells(Cell::new(0, 0).intersect(Cell::new(0, 0)), 2, 3),
768            [Entity::Cell(0, 0)]
769        );
770        assert_eq!(
771            vec_cells(Rows::first().intersect(Cell::new(0, 0)), 2, 3),
772            [Entity::Cell(0, 0)]
773        );
774        // maybe we somehow shall not limit the rows/columns by the max count?
775        assert_eq!(vec_cells(Rows::one(1).intersect(Columns::one(1)), 2, 1), []);
776    }
777
778    #[test]
779    fn object_inverse_test() {
780        assert_eq!(vec_cells(Segment::all().inverse(), 2, 3), []);
781        assert_eq!(
782            vec_cells(Cell::new(0, 0).inverse(), 2, 3),
783            [
784                Entity::Cell(0, 1),
785                Entity::Cell(0, 2),
786                Entity::Cell(1, 0),
787                Entity::Cell(1, 1),
788                Entity::Cell(1, 2)
789            ]
790        );
791        assert_eq!(
792            vec_cells(Rows::first().inverse(), 2, 3),
793            [Entity::Cell(1, 0), Entity::Cell(1, 1), Entity::Cell(1, 2)]
794        );
795        assert_eq!(vec_cells(Rows::first().inverse(), 0, 0), []);
796    }
797
798    fn vec_cells<O: Object<VecRecords<String>>>(
799        o: O,
800        count_rows: usize,
801        count_cols: usize,
802    ) -> Vec<Entity> {
803        let data = vec![vec![String::default(); count_cols]; count_rows];
804        let records = VecRecords::new(data);
805        o.cells(&records).collect::<Vec<_>>()
806    }
807}