use std::cmp::Ordering;
use super::Offset;
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Position {
pub column: u16,
pub row: u16,
}
impl PartialOrd for Position {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let row_ord = self.row.partial_cmp(&other.row);
if let Some(row_ord) = row_ord {
match row_ord {
Ordering::Equal => self.column.partial_cmp(&other.column),
_ => Some(row_ord),
}
} else {
None
}
}
}
impl Position {
pub const ZERO: Position = Position { column: 0, row: 0 };
pub fn new(column: u16, row: u16) -> Self {
Self { column, row }
}
pub fn offset_position(self, position: Position) -> Option<Self> {
self.offset_u16(position.column, position.row)
}
pub fn offset_position_negative(self, position: Position) -> Option<Self> {
self.offset_u16_negative(position.column, position.row)
}
pub fn offset_u16(mut self, x: u16, y: u16) -> Option<Self> {
self.column = self.column.checked_add(x)?;
self.row = self.row.checked_add(y)?;
Some(self)
}
pub fn offset_u16_negative(mut self, x: u16, y: u16) -> Option<Self> {
self.column = self.column.checked_sub(x)?;
self.row = self.row.checked_sub(y)?;
Some(self)
}
pub fn offset_i16(mut self, x: i16, y: i16) -> Option<Self> {
let x = x.try_into().ok()?;
let y = y.try_into().ok()?;
self.column = self.column.checked_add(x)?;
self.row = self.row.checked_add(y)?;
Some(self)
}
pub fn offset_i16_negative(mut self, x: i16, y: i16) -> Option<Self> {
let x = x.try_into().ok()?;
let y = y.try_into().ok()?;
self.column = self.column.checked_sub(x)?;
self.row = self.row.checked_sub(y)?;
Some(self)
}
}
impl From<(u16, u16)> for Position {
fn from(value: (u16, u16)) -> Self {
Self {
column: value.0,
row: value.1,
}
}
}
impl From<Offset> for Position {
fn from(value: Offset) -> Self {
Self {
column: value.x,
row: value.y,
}
}
}