#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u32)]
pub enum IndexKind {
#[default]
Default = 0,
None = 1,
Natural = 2,
YStripes = 3,
}
impl From<tg_geom_sys::tg_index> for IndexKind {
fn from(ix: tg_geom_sys::tg_index) -> Self {
match ix {
tg_geom_sys::tg_index_TG_DEFAULT => IndexKind::Default,
tg_geom_sys::tg_index_TG_NONE => IndexKind::None,
tg_geom_sys::tg_index_TG_NATURAL => IndexKind::Natural,
tg_geom_sys::tg_index_TG_YSTRIPES => IndexKind::YStripes,
_ => unreachable!("unknown index kind: {ix}"),
}
}
}
impl From<IndexKind> for tg_geom_sys::tg_index {
fn from(ix: IndexKind) -> Self {
match ix {
IndexKind::Default => tg_geom_sys::tg_index_TG_DEFAULT,
IndexKind::None => tg_geom_sys::tg_index_TG_NONE,
IndexKind::Natural => tg_geom_sys::tg_index_TG_NATURAL,
IndexKind::YStripes => tg_geom_sys::tg_index_TG_YSTRIPES,
}
}
}
pub fn set_default_index(ix: IndexKind) {
unsafe { tg_geom_sys::tg_env_set_index(ix.into()) }
}
pub fn set_default_index_spread(spread: i32) {
unsafe { tg_geom_sys::tg_env_set_index_spread(spread) }
}
pub fn set_print_fixed_floats(print: bool) {
unsafe { tg_geom_sys::tg_env_set_print_fixed_floats(print) }
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Point, Ring};
fn p(x: f64, y: f64) -> Point {
Point::new(x, y)
}
fn octagon() -> Vec<Point> {
vec![
p(3.0, 0.0),
p(7.0, 0.0),
p(10.0, 3.0),
p(10.0, 7.0),
p(7.0, 10.0),
p(3.0, 10.0),
p(0.0, 7.0),
p(0.0, 3.0),
p(3.0, 0.0),
]
}
#[test]
fn test_index_kind_variants() {
assert_eq!(IndexKind::Default as u32, 0);
assert_eq!(IndexKind::None as u32, 1);
assert_eq!(IndexKind::Natural as u32, 2);
assert_eq!(IndexKind::YStripes as u32, 3);
}
#[test]
fn test_index_kind_default() {
let ix: IndexKind = Default::default();
assert_eq!(ix, IndexKind::Default);
}
#[test]
fn test_index_kind_copy() {
let ix1 = IndexKind::Natural;
let ix2 = ix1;
assert_eq!(ix1, ix2);
}
#[test]
fn test_index_kind_eq() {
assert_eq!(IndexKind::None, IndexKind::None);
assert_ne!(IndexKind::None, IndexKind::Natural);
}
#[test]
fn test_index_kind_debug() {
let debug_str = format!("{:?}", IndexKind::Natural);
assert!(debug_str.contains("Natural"));
}
#[test]
fn test_index_kind_sys_roundtrip() {
let kinds = [
IndexKind::Default,
IndexKind::None,
IndexKind::Natural,
IndexKind::YStripes,
];
for kind in &kinds {
let sys_kind: tg_geom_sys::tg_index = (*kind).into();
let back: IndexKind = sys_kind.into();
assert_eq!(*kind, back);
}
}
#[test]
fn test_set_default_index() {
set_default_index(IndexKind::Natural);
set_default_index(IndexKind::None);
set_default_index(IndexKind::YStripes);
set_default_index(IndexKind::Default);
}
#[test]
fn test_set_default_index_spread() {
set_default_index_spread(4);
set_default_index_spread(8);
set_default_index_spread(16);
}
#[test]
fn test_set_print_fixed_floats() {
set_print_fixed_floats(true);
set_print_fixed_floats(false);
}
#[test]
fn test_ring_index_kinds() {
let points = octagon();
let ring_default = Ring::new(&points).unwrap();
let ring_none = Ring::new_ix(&points, IndexKind::None).unwrap();
let ring_natural = Ring::new_ix(&points, IndexKind::Natural).unwrap();
let ring_ystripes = Ring::new_ix(&points, IndexKind::YStripes).unwrap();
assert_eq!(ring_default.num_points(), ring_none.num_points());
assert_eq!(ring_default.num_points(), ring_natural.num_points());
assert_eq!(ring_default.num_points(), ring_ystripes.num_points());
assert_eq!(ring_default.area(), ring_none.area());
assert_eq!(ring_default.area(), ring_natural.area());
assert_eq!(ring_default.area(), ring_ystripes.area());
}
#[test]
fn test_ring_index_properties() {
let ring_natural = Ring::new_ix(&octagon(), IndexKind::Natural).unwrap();
let spread = ring_natural.index_spread();
let num_levels = ring_natural.index_num_levels();
assert!(spread >= 0);
assert!(num_levels >= 0);
if num_levels > 0 {
let level0_rects = ring_natural.index_level_num_rects(0);
assert!(level0_rects >= 0);
}
}
#[test]
fn test_ring_none_index() {
let ring_none = Ring::new_ix(&octagon(), IndexKind::None).unwrap();
assert_eq!(ring_none.index_num_levels(), 0);
}
}