use retroglyph_core::grid::Size;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub enum Density {
Touch,
Mouse,
}
impl Density {
pub const DEFAULT_BREAKPOINT_WIDTH: u16 = 64;
#[must_use]
pub const fn min_target_size(self) -> Size {
match self {
Self::Touch => Size::new(6, 3),
Self::Mouse => Size::new(6, 1),
}
}
#[must_use]
pub const fn for_width(width: u16) -> Self {
if width < Self::DEFAULT_BREAKPOINT_WIDTH {
Self::Touch
} else {
Self::Mouse
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use retroglyph_core::grid::HasSize;
#[test]
fn touch_rows_are_taller_than_mouse_for_fingertip_targets() {
let touch = Density::Touch.min_target_size();
let mouse = Density::Mouse.min_target_size();
assert!(touch.height() > mouse.height());
}
#[test]
fn mouse_still_claims_more_than_a_single_cell_wide() {
let size = Density::Mouse.min_target_size();
assert!(size.width() > 1);
}
#[test]
fn for_width_picks_touch_below_the_default_breakpoint() {
assert_eq!(
Density::for_width(Density::DEFAULT_BREAKPOINT_WIDTH - 1),
Density::Touch
);
}
#[test]
fn for_width_picks_mouse_at_or_above_the_default_breakpoint() {
assert_eq!(
Density::for_width(Density::DEFAULT_BREAKPOINT_WIDTH),
Density::Mouse
);
assert_eq!(
Density::for_width(Density::DEFAULT_BREAKPOINT_WIDTH + 1),
Density::Mouse
);
}
#[cfg(feature = "serde")]
#[test]
fn serializes_as_a_plain_string() {
let json = serde_json::to_string(&Density::Touch).expect("serialize");
assert_eq!(json, "\"Touch\"");
assert_eq!(
serde_json::from_str::<Density>(&json).expect("deserialize"),
Density::Touch
);
}
}