#[derive(Debug, Clone)]
pub enum Coord {
Cartesian {
xlim: Option<(f32, f32)>,
ylim: Option<(f32, f32)>,
flip: bool,
},
Polar {
start: f32,
direction: i8,
},
Fixed {
ratio: f32,
},
}
impl Default for Coord {
fn default() -> Self {
Coord::cartesian()
}
}
impl Coord {
#[must_use]
pub fn cartesian() -> Self {
Coord::Cartesian { xlim: None, ylim: None, flip: false }
}
#[must_use]
pub fn polar() -> Self {
Coord::Polar { start: 0.0, direction: 1 }
}
#[must_use]
pub fn fixed(ratio: f32) -> Self {
Coord::Fixed { ratio }
}
#[must_use]
pub fn xlim(mut self, min: f32, max: f32) -> Self {
if let Coord::Cartesian { ref mut xlim, .. } = self {
*xlim = Some((min, max));
}
self
}
#[must_use]
pub fn ylim(mut self, min: f32, max: f32) -> Self {
if let Coord::Cartesian { ref mut ylim, .. } = self {
*ylim = Some((min, max));
}
self
}
#[must_use]
pub fn flip(mut self) -> Self {
if let Coord::Cartesian { flip: ref mut f, .. } = self {
*f = true;
}
self
}
#[must_use]
pub fn start_angle(mut self, start: f32) -> Self {
if let Coord::Polar { start: ref mut s, .. } = self {
*s = start;
}
self
}
#[must_use]
pub fn direction(mut self, dir: i8) -> Self {
if let Coord::Polar { direction: ref mut d, .. } = self {
*d = if dir >= 0 { 1 } else { -1 };
}
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_coord_cartesian() {
let c = Coord::cartesian().xlim(0.0, 10.0).ylim(-5.0, 5.0);
match c {
Coord::Cartesian { xlim, ylim, flip } => {
assert_eq!(xlim, Some((0.0, 10.0)));
assert_eq!(ylim, Some((-5.0, 5.0)));
assert!(!flip);
}
_ => panic!("Expected Cartesian"),
}
}
#[test]
fn test_coord_flip() {
let c = Coord::cartesian().flip();
match c {
Coord::Cartesian { flip, .. } => assert!(flip),
_ => panic!("Expected Cartesian"),
}
}
#[test]
fn test_coord_polar() {
let c = Coord::polar().start_angle(std::f32::consts::PI).direction(-1);
match c {
Coord::Polar { start, direction } => {
assert!((start - std::f32::consts::PI).abs() < 0.001);
assert_eq!(direction, -1);
}
_ => panic!("Expected Polar"),
}
}
#[test]
fn test_coord_fixed() {
let c = Coord::fixed(1.5);
match c {
Coord::Fixed { ratio } => {
assert!((ratio - 1.5).abs() < 0.001);
}
_ => panic!("Expected Fixed"),
}
}
#[test]
fn test_coord_default() {
let c = Coord::default();
assert!(matches!(c, Coord::Cartesian { xlim: None, ylim: None, flip: false }));
}
#[test]
fn test_xlim_on_non_cartesian() {
let c = Coord::polar().xlim(0.0, 10.0);
assert!(matches!(c, Coord::Polar { .. }));
}
#[test]
fn test_ylim_on_non_cartesian() {
let c = Coord::fixed(1.0).ylim(0.0, 10.0);
assert!(matches!(c, Coord::Fixed { .. }));
}
#[test]
fn test_flip_on_non_cartesian() {
let c = Coord::polar().flip();
assert!(matches!(c, Coord::Polar { .. }));
}
#[test]
fn test_start_angle_on_non_polar() {
let c = Coord::cartesian().start_angle(1.0);
assert!(matches!(c, Coord::Cartesian { .. }));
}
#[test]
fn test_direction_on_non_polar() {
let c = Coord::fixed(1.0).direction(-1);
assert!(matches!(c, Coord::Fixed { .. }));
}
#[test]
fn test_direction_positive() {
let c = Coord::polar().direction(1);
match c {
Coord::Polar { direction, .. } => {
assert_eq!(direction, 1);
}
_ => panic!("Expected Polar"),
}
}
#[test]
fn test_direction_zero() {
let c = Coord::polar().direction(0);
match c {
Coord::Polar { direction, .. } => {
assert_eq!(direction, 1);
}
_ => panic!("Expected Polar"),
}
}
#[test]
fn test_coord_debug_clone() {
let c = Coord::cartesian().xlim(0.0, 10.0);
let c2 = c.clone();
let _ = format!("{c2:?}");
}
#[test]
fn test_polar_debug_clone() {
let c = Coord::polar().start_angle(0.5);
let c2 = c.clone();
let _ = format!("{c2:?}");
}
#[test]
fn test_fixed_debug_clone() {
let c = Coord::fixed(2.0);
let c2 = c.clone();
let _ = format!("{c2:?}");
}
}