1use std::fmt;
2
3#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash)]
5pub struct Size {
6 pub width: u16,
7 pub height: u16,
8}
9
10impl Size {
11 pub const MAX: Self = Self::new(u16::MAX, u16::MAX);
12 pub const MIN: Self = Self::ZERO;
13 pub const ZERO: Self = Self::new(0, 0);
14
15 pub const fn new(width: u16, height: u16) -> Self {
16 Self { width, height }
17 }
18
19 pub const fn area(self) -> u32 {
20 self.width as u32 * self.height as u32
21 }
22}
23
24impl From<(u16, u16)> for Size {
25 fn from((width, height): (u16, u16)) -> Self {
26 Self { width, height }
27 }
28}
29
30impl From<Size> for (u16, u16) {
31 fn from(size: Size) -> Self {
32 (size.width, size.height)
33 }
34}
35
36impl fmt::Display for Size {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 write!(f, "{}x{}", self.width, self.height)
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 #[test]
47 fn size_new() {
48 let s = Size::new(10, 20);
49 assert_eq!(s.width, 10);
50 assert_eq!(s.height, 20);
51 }
52
53 #[test]
54 fn size_area() {
55 assert_eq!(Size::new(10, 20).area(), 200);
56 assert_eq!(Size::ZERO.area(), 0);
57 }
58
59 #[test]
60 fn size_from_tuple() {
61 let s: Size = (5, 7).into();
62 assert_eq!(s, Size::new(5, 7));
63 }
64
65 #[test]
66 fn size_into_tuple() {
67 let s = Size::new(3, 4);
68 let (w, h): (u16, u16) = s.into();
69 assert_eq!(w, 3);
70 assert_eq!(h, 4);
71 }
72
73 #[test]
74 fn size_display() {
75 assert_eq!(Size::new(10, 20).to_string(), "10x20");
76 }
77
78 #[test]
79 fn size_max_area() {
80 assert_eq!(Size::MAX.area(), u16::MAX as u32 * u16::MAX as u32);
81 }
82}