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