#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Breakpoint {
Base,
Sm,
Md,
Lg,
Xl,
Xxl,
}
impl Breakpoint {
pub const fn min_width(self) -> f32 {
match self {
Self::Base => 0.0,
Self::Sm => 640.0,
Self::Md => 768.0,
Self::Lg => 1024.0,
Self::Xl => 1280.0,
Self::Xxl => 1536.0,
}
}
pub fn at(width: f32) -> Self {
if width >= Self::Xxl.min_width() {
Self::Xxl
} else if width >= Self::Xl.min_width() {
Self::Xl
} else if width >= Self::Lg.min_width() {
Self::Lg
} else if width >= Self::Md.min_width() {
Self::Md
} else if width >= Self::Sm.min_width() {
Self::Sm
} else {
Self::Base
}
}
}
pub struct Breakpoints;
impl Breakpoints {
pub fn up(width: f32, bp: Breakpoint) -> bool {
width >= bp.min_width()
}
pub fn down(width: f32, bp: Breakpoint) -> bool {
width < bp.min_width()
}
pub fn only(width: f32, bp: Breakpoint) -> bool {
Breakpoint::at(width) == bp
}
pub fn is_sm(width: f32) -> bool {
Self::up(width, Breakpoint::Sm)
}
pub fn is_md(width: f32) -> bool {
Self::up(width, Breakpoint::Md)
}
pub fn is_lg(width: f32) -> bool {
Self::up(width, Breakpoint::Lg)
}
pub fn is_xl(width: f32) -> bool {
Self::up(width, Breakpoint::Xl)
}
pub fn is_xxl(width: f32) -> bool {
Self::up(width, Breakpoint::Xxl)
}
}
#[cfg(test)]
mod tests {
use super::{Breakpoint, Breakpoints};
#[test]
fn at_classifies_each_band_at_and_below_its_edge() {
assert_eq!(Breakpoint::at(0.0), Breakpoint::Base);
assert_eq!(Breakpoint::at(639.9), Breakpoint::Base);
assert_eq!(Breakpoint::at(640.0), Breakpoint::Sm);
assert_eq!(Breakpoint::at(767.9), Breakpoint::Sm);
assert_eq!(Breakpoint::at(768.0), Breakpoint::Md);
assert_eq!(Breakpoint::at(1024.0), Breakpoint::Lg);
assert_eq!(Breakpoint::at(1280.0), Breakpoint::Xl);
assert_eq!(Breakpoint::at(1535.9), Breakpoint::Xl);
assert_eq!(Breakpoint::at(1536.0), Breakpoint::Xxl);
assert_eq!(Breakpoint::at(4000.0), Breakpoint::Xxl);
}
#[test]
fn degenerate_widths_fall_to_base() {
assert_eq!(Breakpoint::at(-100.0), Breakpoint::Base);
assert_eq!(Breakpoint::at(f32::NAN), Breakpoint::Base);
}
#[test]
fn up_down_only_agree_with_at() {
assert!(Breakpoints::up(768.0, Breakpoint::Md));
assert!(!Breakpoints::up(767.0, Breakpoint::Md));
assert!(Breakpoints::down(767.0, Breakpoint::Md));
assert!(!Breakpoints::down(768.0, Breakpoint::Md));
assert!(Breakpoints::only(800.0, Breakpoint::Md));
assert!(!Breakpoints::only(1024.0, Breakpoint::Md));
assert!(Breakpoints::is_md(768.0));
assert!(!Breakpoints::is_lg(1023.0));
assert!(Breakpoints::is_xxl(1536.0));
assert!(Breakpoint::Base < Breakpoint::Sm);
assert!(Breakpoint::Lg < Breakpoint::Xxl);
}
}