mat/
dimensions.rs

1#[cfg(feature="serde")]
2use serde::{Deserialize, Serialize};
3
4use super::{Coordinate, Rectangle};
5
6/// Non-zero rectangle dimensions
7///
8/// ```
9/// # use mat::{Dimensions, Rectangle};
10/// let d = Dimensions::from ((3, 2));
11/// assert_eq!(d.rows, 3);
12/// assert_eq!(d.columns,  2);
13/// assert_eq!(d.area(), 6);
14/// assert!( d.contains ((1, 1).into()));
15/// assert!(!d.contains ((4, 1).into()));
16/// assert!(!d.contains ((1, 3).into()));
17/// let rect = Rectangle::from (d);
18/// assert_eq!(rect.min(), (0, 0).into());
19/// assert_eq!(rect.max(), (2, 1).into());
20/// ```
21#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
22#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
23pub struct Dimensions {
24  pub rows    : usize,
25  pub columns : usize
26}
27
28impl Dimensions {
29  /// Rows * columns
30  #[inline]
31  pub const fn area (&self) -> usize {
32    self.rows * self.columns
33  }
34  /// Return true if the coordinate fits within `self`'s columns and rows, false
35  /// otherwise
36  #[inline]
37  pub fn contains (&self, Coordinate { row, column } : Coordinate) -> bool {
38    self.contains_rc (row, column)
39  }
40  #[inline]
41  pub fn contains_rc (&self, row : usize, column : usize) -> bool {
42    row < self.rows && column < self.columns
43  }
44  #[inline]
45  pub fn row (&self, row : usize) -> Option <Rectangle> {
46    Rectangle::from (*self).row (row)
47  }
48  #[inline]
49  pub fn column (&self, column : usize) -> Option <Rectangle> {
50    Rectangle::from (*self).column (column)
51  }
52  /// Top row
53  #[inline]
54  pub fn top (&self) -> Option <Rectangle> {
55    self.row (0)
56  }
57  /// Bottom row
58  #[inline]
59  pub fn bottom (&self) -> Option <Rectangle> {
60    self.row (self.rows-1)
61  }
62  /// Left column
63  #[inline]
64  pub fn left (&self) -> Option <Rectangle> {
65    self.column (0)
66  }
67  /// Right column
68  #[inline]
69  pub fn right (&self) -> Option <Rectangle> {
70    self.column (self.columns-1)
71  }
72}
73impl From <(usize, usize)> for Dimensions {
74  fn from ((rows, columns) : (usize, usize)) -> Self {
75    Dimensions { rows, columns }
76  }
77}
78impl From <Dimensions> for (usize, usize) {
79  fn from (Dimensions { rows, columns } : Dimensions) -> Self {
80    (rows, columns)
81  }
82}
83impl From <[usize; 2]> for Dimensions {
84  fn from ([rows, columns] : [usize; 2]) -> Self {
85    Dimensions { rows, columns }
86  }
87}
88impl From <Dimensions> for [usize; 2] {
89  fn from (Dimensions { rows, columns } : Dimensions) -> Self {
90    [rows, columns]
91  }
92}
93impl std::ops::Add for Dimensions {
94  type Output = Dimensions;
95  fn add (self, rhs : Dimensions) -> Dimensions {
96    (self.rows + rhs.rows, self.columns + rhs.columns).into()
97  }
98}
99impl std::ops::Sub for Dimensions {
100  type Output = Dimensions;
101  fn sub (self, rhs : Dimensions) -> Dimensions {
102    (self.rows - rhs.rows, self.columns - rhs.columns).into()
103  }
104}