#![doc = include_str!("../../docs/matrix/items.md")]
#[derive(PartialEq, Clone, Debug)]
pub struct Coordinates {
row: usize,
column: usize,
}
impl Coordinates {
#[must_use]
pub fn new(row: usize, column: usize) -> Self {
Self { row, column }
}
#[must_use]
pub fn row(&self) -> usize {
self.row
}
#[must_use]
pub fn column(&self) -> usize {
self.column
}
pub fn mut_row(&mut self) -> &mut usize {
&mut self.row
}
pub fn mut_column(&mut self) -> &mut usize {
&mut self.column
}
#[must_use]
pub fn is_origin(&self) -> bool {
self.row == 0 && self.column == 0
}
}
impl std::fmt::Display for Coordinates {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "({}, {})", self.row, self.column)
}
}
impl From<Coordinates> for (usize, usize) {
fn from(coordinates: Coordinates) -> Self {
(coordinates.row, coordinates.column)
}
}
impl From<(usize, usize)> for Coordinates {
fn from(coordinates: (usize, usize)) -> Self {
Self::new(coordinates.0, coordinates.1)
}
}
impl PartialOrd for Coordinates {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
match self.row.cmp(&other.row) {
std::cmp::Ordering::Greater => Some(std::cmp::Ordering::Greater),
std::cmp::Ordering::Less => Some(std::cmp::Ordering::Less),
std::cmp::Ordering::Equal => match self.column.cmp(&other.column) {
std::cmp::Ordering::Greater => Some(std::cmp::Ordering::Greater),
std::cmp::Ordering::Less => Some(std::cmp::Ordering::Less),
std::cmp::Ordering::Equal => Some(std::cmp::Ordering::Equal),
},
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use rstest::{fixture, rstest};
#[fixture]
fn coordinates() -> Coordinates {
Coordinates { row: 1, column: 2 }
}
#[rstest]
fn clone(coordinates: Coordinates) {
assert_eq!(coordinates.clone(), coordinates);
}
#[rstest]
fn debug(coordinates: Coordinates) {
assert_eq!(
format!("{coordinates:?}"),
"Coordinates { row: 1, column: 2 }"
);
}
#[rstest]
fn display(coordinates: Coordinates) {
assert_eq!(format!("{coordinates}"), "(1, 2)");
}
#[rstest]
fn new(coordinates: Coordinates) {
assert_eq!(Coordinates::new(1, 2), coordinates);
}
#[rstest]
fn row(coordinates: Coordinates) {
assert_eq!(coordinates.row(), 1);
}
#[rstest]
fn column(coordinates: Coordinates) {
assert_eq!(coordinates.column(), 2);
}
#[rstest]
fn mut_row(mut coordinates: Coordinates) {
*coordinates.mut_row() = 3;
assert_eq!(Coordinates::new(3, 2), coordinates);
}
#[rstest]
fn mut_column(mut coordinates: Coordinates) {
*coordinates.mut_column() = 4;
assert_eq!(Coordinates::new(1, 4), coordinates);
}
#[rstest]
fn is_origin(coordinates: Coordinates) {
assert!(!coordinates.is_origin());
assert!(Coordinates::new(0, 0).is_origin());
}
#[rstest]
fn from_coordinates_to_couple_usize(coordinates: Coordinates) {
assert_eq!(<(usize, usize)>::from(coordinates), (1, 2));
}
#[rstest]
fn from_couple_usize_to_coordinates(coordinates: Coordinates) {
assert_eq!(Coordinates::from((1, 2)), coordinates);
}
#[rstest]
fn partial_cmp(coordinates: Coordinates) {
assert!(coordinates == Coordinates::new(1, 2));
assert!(coordinates < Coordinates::new(2, 2));
assert!(coordinates > Coordinates::new(0, 2));
assert!(coordinates < Coordinates::new(1, 3));
assert!(coordinates > Coordinates::new(1, 1));
assert_eq!(
coordinates.partial_cmp(&coordinates),
Some(std::cmp::Ordering::Equal)
);
}
}