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