1mod 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
70pub trait Object<R> {
74 type Iter: Iterator<Item = Entity>;
76
77 fn cells(&self, records: &R) -> Self::Iter;
79
80 fn and<O>(self, rhs: O) -> UnionCombination<Self, O, R>
83 where
84 Self: Sized,
85 {
86 UnionCombination::new(self, rhs)
87 }
88
89 fn not<O>(self, rhs: O) -> DiffCombination<Self, O, R>
91 where
92 Self: Sized,
93 {
94 DiffCombination::new(self, rhs)
95 }
96
97 fn intersect<O>(self, rhs: O) -> IntersectionCombination<Self, O, R>
99 where
100 Self: Sized,
101 {
102 IntersectionCombination::new(self, rhs)
103 }
104
105 fn inverse(self) -> InversionCombination<Self, R>
107 where
108 Self: Sized,
109 {
110 InversionCombination::new(self)
111 }
112}
113
114#[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#[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#[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#[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#[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#[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#[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#[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 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}