nsys-mat 0.5.4

Dynamically sized 2d storage with rectangular iterators and in-place resizing
Documentation
#[cfg(feature="serde")]
use serde::{Deserialize, Serialize};

use super::{Coordinate, Rectangle};

/// Non-zero rectangle dimensions
///
/// ```
/// # use mat::{Dimensions, Rectangle};
/// let d = Dimensions::from ((3, 2));
/// assert_eq!(d.rows, 3);
/// assert_eq!(d.columns,  2);
/// assert_eq!(d.area(), 6);
/// assert!( d.contains ((1, 1).into()));
/// assert!(!d.contains ((4, 1).into()));
/// assert!(!d.contains ((1, 3).into()));
/// let rect = Rectangle::from (d);
/// assert_eq!(rect.min(), (0, 0).into());
/// assert_eq!(rect.max(), (2, 1).into());
/// ```
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct Dimensions {
  pub rows    : usize,
  pub columns : usize
}

impl Dimensions {
  /// Rows * columns
  #[inline]
  pub const fn area (&self) -> usize {
    self.rows * self.columns
  }
  /// Return true if the coordinate fits within `self`'s columns and rows, false
  /// otherwise
  #[inline]
  pub fn contains (&self, Coordinate { row, column } : Coordinate) -> bool {
    self.contains_rc (row, column)
  }
  #[inline]
  pub fn contains_rc (&self, row : usize, column : usize) -> bool {
    row < self.rows && column < self.columns
  }
  #[inline]
  pub fn row (&self, row : usize) -> Option <Rectangle> {
    Rectangle::from (*self).row (row)
  }
  #[inline]
  pub fn column (&self, column : usize) -> Option <Rectangle> {
    Rectangle::from (*self).column (column)
  }
  /// Top row
  #[inline]
  pub fn top (&self) -> Option <Rectangle> {
    self.row (0)
  }
  /// Bottom row
  #[inline]
  pub fn bottom (&self) -> Option <Rectangle> {
    self.row (self.rows-1)
  }
  /// Left column
  #[inline]
  pub fn left (&self) -> Option <Rectangle> {
    self.column (0)
  }
  /// Right column
  #[inline]
  pub fn right (&self) -> Option <Rectangle> {
    self.column (self.columns-1)
  }
}
impl From <(usize, usize)> for Dimensions {
  fn from ((rows, columns) : (usize, usize)) -> Self {
    Dimensions { rows, columns }
  }
}
impl From <Dimensions> for (usize, usize) {
  fn from (Dimensions { rows, columns } : Dimensions) -> Self {
    (rows, columns)
  }
}
impl From <[usize; 2]> for Dimensions {
  fn from ([rows, columns] : [usize; 2]) -> Self {
    Dimensions { rows, columns }
  }
}
impl From <Dimensions> for [usize; 2] {
  fn from (Dimensions { rows, columns } : Dimensions) -> Self {
    [rows, columns]
  }
}
impl std::ops::Add for Dimensions {
  type Output = Dimensions;
  fn add (self, rhs : Dimensions) -> Dimensions {
    (self.rows + rhs.rows, self.columns + rhs.columns).into()
  }
}
impl std::ops::Sub for Dimensions {
  type Output = Dimensions;
  fn sub (self, rhs : Dimensions) -> Dimensions {
    (self.rows - rhs.rows, self.columns - rhs.columns).into()
  }
}