#![forbid(unsafe_code)]
#![doc = include_str!("../README.md")]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum ViewportOrientation {
Portrait,
Landscape,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum Density {
Compact,
Comfortable,
Spacious,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum ViewportClass {
Xs,
Sm,
Md,
Lg,
Xl,
Xxl,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct DisplayScale(u32);
impl DisplayScale {
pub fn from_milli(value: u32) -> Self {
Self(value)
}
pub fn one() -> Self {
Self(1_000)
}
pub fn milli(self) -> u32 {
self.0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ViewportSize {
width: u32,
height: u32,
}
impl ViewportSize {
pub fn new(width: u32, height: u32) -> Self {
Self { width, height }
}
pub fn width(self) -> u32 {
self.width
}
pub fn height(self) -> u32 {
self.height
}
pub fn orientation(self) -> ViewportOrientation {
if self.width >= self.height {
ViewportOrientation::Landscape
} else {
ViewportOrientation::Portrait
}
}
pub fn class(self) -> ViewportClass {
match self.width {
0..=479 => ViewportClass::Xs,
480..=767 => ViewportClass::Sm,
768..=1023 => ViewportClass::Md,
1024..=1279 => ViewportClass::Lg,
1280..=1535 => ViewportClass::Xl,
_ => ViewportClass::Xxl,
}
}
}
#[cfg(test)]
mod tests {
use super::{Density, DisplayScale, ViewportClass, ViewportOrientation, ViewportSize};
#[test]
fn classifies_viewport_size() {
let phone = ViewportSize::new(390, 844);
let desktop = ViewportSize::new(1440, 900);
assert_eq!(phone.orientation(), ViewportOrientation::Portrait);
assert_eq!(phone.class(), ViewportClass::Xs);
assert_eq!(desktop.orientation(), ViewportOrientation::Landscape);
assert_eq!(desktop.class(), ViewportClass::Xl);
}
#[test]
fn stores_density_and_scale() {
let scale = DisplayScale::from_milli(1_250);
assert_eq!(Density::Comfortable, Density::Comfortable);
assert_eq!(DisplayScale::one().milli(), 1_000);
assert_eq!(scale.milli(), 1_250);
}
}