use core::fmt;
use crate::{Color, Point};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StoneId(pub u32);
impl StoneId {
#[must_use]
pub const fn new(value: u32) -> Self {
Self(value)
}
#[must_use]
pub const fn get(self) -> u32 {
self.0
}
}
impl fmt::Display for StoneId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Stone {
pub id: StoneId,
pub color: Color,
#[cfg_attr(feature = "serde", serde(rename = "pos"))]
pub position: Point,
}
impl Stone {
#[must_use]
pub const fn new(id: StoneId, color: Color, position: Point) -> Self {
Self {
id,
color,
position,
}
}
}
#[cfg(test)]
mod tests {
#![allow(clippy::unwrap_used, clippy::expect_used)]
use super::{Stone, StoneId};
use crate::{Color, Point};
#[test]
fn ids_order_and_display_as_numbers() {
assert!(StoneId::new(2) < StoneId::new(10));
assert_eq!(StoneId::new(7).get(), 7);
assert_eq!(StoneId::new(7).to_string(), "7");
}
#[test]
fn stone_equality_is_exact_in_its_position() {
let a = Stone::new(StoneId::new(0), Color::Black, Point::new(4.0, 4.0));
let b = Stone::new(StoneId::new(0), Color::Black, Point::new(4.0, 4.0));
let nudged = f64::from_bits(4.0_f64.to_bits() + 1);
let c = Stone::new(StoneId::new(0), Color::Black, Point::new(4.0, nudged));
assert_eq!(a, b);
assert_ne!(a, c);
}
}