use crate::page_description::color::CT_Color;
#[derive(Debug, Clone, PartialEq)]
pub struct Point {
pub x: f64,
pub y: f64,
pub edge_flag: Option<u8>,
pub color: Option<CT_Color>,
}
pub mod edge_flag {
pub const CLOSED: u8 = 0;
pub const OPEN: u8 = 1;
}
impl Point {
#[must_use]
pub fn new(x: f64, y: f64) -> Self {
Self {
x,
y,
edge_flag: None,
color: None,
}
}
#[must_use]
pub fn with_edge_flag(mut self, flag: u8) -> Self {
self.edge_flag = Some(flag);
self
}
#[must_use]
pub fn with_color(mut self, color: CT_Color) -> Self {
self.color = Some(color);
self
}
#[must_use]
pub fn set_x(mut self, x: f64) -> Self {
self.x = x;
self
}
#[must_use]
pub fn set_y(mut self, y: f64) -> Self {
self.y = y;
self
}
}
impl From<(f64, f64)> for Point {
fn from((x, y): (f64, f64)) -> Self {
Self::new(x, y)
}
}
impl std::fmt::Display for Point {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} {}", self.x, self.y)
}
}
#[cfg(test)]
mod tests {
use super::*;
fn approx(a: f64, b: f64) -> bool {
(a - b).abs() < f64::EPSILON
}
#[test]
fn test_point_new() {
let p = Point::new(1.5, 2.5);
assert!(approx(p.x, 1.5));
assert!(approx(p.y, 2.5));
assert!(p.edge_flag.is_none());
}
#[test]
fn test_builders() {
let p = Point::new(0.0, 0.0)
.with_edge_flag(edge_flag::OPEN)
.set_x(10.0)
.set_y(20.0);
assert!(approx(p.x, 10.0));
assert_eq!(p.edge_flag, Some(1));
assert!(p.color.is_none());
}
#[test]
fn test_from_tuple_and_display() {
let p = Point::from((3.0, 4.0));
assert_eq!(p.to_string(), "3 4");
}
}