1use std::{
2 fmt::Display,
3 hash::{Hash, Hasher},
4 mem,
5 ops::Range,
6};
7
8use glam::Vec2;
9pub use Unit::*;
10
11#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
13pub enum Unit {
14 Px(f32),
18 Pt(f32),
22 Pc(f32),
27 Vw(f32),
29 Vh(f32),
31 Em(f32),
36}
37
38impl Eq for Unit {}
39
40impl Hash for Unit {
41 fn hash<H: Hasher>(&self, state: &mut H) {
42 mem::discriminant(self).hash(state);
43
44 match self {
45 Px(value) => value.to_bits().hash(state),
46 Pt(value) => value.to_bits().hash(state),
47 Pc(value) => value.to_bits().hash(state),
48 Vw(value) => value.to_bits().hash(state),
49 Vh(value) => value.to_bits().hash(state),
50 Em(value) => value.to_bits().hash(state),
51 }
52 }
53}
54
55impl Default for Unit {
56 fn default() -> Self {
57 Self::ZERO
58 }
59}
60
61impl Unit {
62 pub const ZERO: Self = Px(0.0);
63
64 pub fn pixels(self, range: Range<f32>, scale: f32, window_size: Vec2) -> f32 {
65 match self {
66 Px(value) => value,
67 Pt(value) => value * 96.0 / 72.0 * scale,
68 Pc(value) => value * (range.end - range.start) / 100.0,
69 Vw(value) => value * window_size.x / 100.0,
70 Vh(value) => value * window_size.y / 100.0,
71 Em(value) => value * 16.0 * scale,
72 }
73 }
74}
75
76impl Display for Unit {
77 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78 match self {
79 Px(value) => write!(f, "{}px", value),
80 Pt(value) => write!(f, "{}pt", value),
81 Pc(value) => write!(f, "{}%", value),
82 Vw(value) => write!(f, "{}vw", value),
83 Vh(value) => write!(f, "{}vh", value),
84 Em(value) => write!(f, "{}em", value),
85 }
86 }
87}