Skip to main content

photon_ui/layout/
size.rs

1use std::fmt;
2
3/// Dimensions in the terminal (width × height).
4#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash)]
5pub struct Size {
6    /// Width in columns.
7    pub width: u16,
8    /// Height in rows.
9    pub height: u16,
10}
11
12impl Size {
13    /// The largest possible size.
14    pub const MAX: Self = Self::new(u16::MAX, u16::MAX);
15    /// The smallest possible size (same as [`ZERO`](Size::ZERO)).
16    pub const MIN: Self = Self::ZERO;
17    /// Zero width and height.
18    pub const ZERO: Self = Self::new(0, 0);
19
20    /// Create a new size with the given width and height.
21    pub const fn new(width: u16, height: u16) -> Self {
22        Self { width, height }
23    }
24
25    /// Total number of cells (`width * height`).
26    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}