1use crate::{DimLocs, Loc, Scale};
2use std::fmt::{Debug, Display, Formatter};
3
4#[derive(Copy, Clone, Eq, PartialEq, Hash, Default)]
6pub struct Dim {
7 pub w: Scale,
8 pub h: Scale,
9}
10
11impl Dim {
12 pub const fn new(w: Scale, h: Scale) -> Self {
16 Self { w, h }
17 }
18}
19
20impl From<(Scale, Scale)> for Dim {
21 fn from((w, h): (Scale, Scale)) -> Self {
22 Self { w, h }
23 }
24}
25
26impl From<Dim> for (Scale, Scale) {
27 fn from(dims: Dim) -> Self {
28 (dims.w, dims.h)
29 }
30}
31
32impl Dim {
33 pub const fn size(self) -> usize {
37 self.w as usize * self.h as usize
38 }
39
40 pub const fn contains(self, loc: Loc) -> bool {
42 loc.x < self.w && loc.y < self.h
43 }
44}
45
46impl Dim {
47 pub fn locs(self) -> DimLocs {
51 DimLocs::from(self)
52 }
53}
54
55impl Debug for Dim {
56 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
57 write!(f, "{}", self)
58 }
59}
60
61impl Display for Dim {
62 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
63 write!(f, "{}x{}", self.w, self.h)
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use crate::{Dim, Loc, Scale};
70
71 #[test]
72 fn size() {
73 let test_cases: &[(Scale, Scale, usize)] = &[
74 (3, 4, 12), (0, 5, 0), (5, 0, 0), (1, 1, 1), (
79 Scale::MAX,
80 Scale::MAX,
81 Scale::MAX as usize * Scale::MAX as usize,
82 ), ];
84
85 for &(w, h, expected) in test_cases {
86 assert_eq!(Dim::new(w, h).size(), expected);
87 }
88 }
89
90 #[test]
91 fn contains() {
92 let test_cases: &[(Dim, Loc, bool)] = &[
93 (Dim::new(3, 3), Loc::new(0, 0), true), (Dim::new(3, 3), Loc::new(2, 2), true), (Dim::new(3, 3), Loc::new(1, 0), true), (Dim::new(3, 3), Loc::new(3, 0), false), (Dim::new(3, 3), Loc::new(0, 3), false), (Dim::new(3, 3), Loc::new(3, 3), false), (Dim::new(0, 0), Loc::new(0, 0), false), ];
101
102 for &(dim, loc, expected) in test_cases {
103 assert_eq!(dim.contains(loc), expected);
104 }
105 }
106}