Skip to main content

slt/
rect.rs

1/// An axis-aligned rectangle with `u32` coordinates.
2///
3/// Uses `u32` rather than `u16` to avoid overflow bugs that affect other TUI
4/// libraries on large terminals. All coordinates are in terminal columns and
5/// rows, with `(0, 0)` at the top-left.
6///
7/// Note: [`Rect::right`] and [`Rect::bottom`] return **exclusive** bounds
8/// (one past the last column/row), consistent with Rust range conventions.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
10pub struct Rect {
11    /// Left edge column, inclusive.
12    pub x: u32,
13    /// Top edge row, inclusive.
14    pub y: u32,
15    /// Width in terminal columns.
16    pub width: u32,
17    /// Height in terminal rows.
18    pub height: u32,
19}
20
21impl Rect {
22    /// Create a new rectangle from position and size.
23    #[inline]
24    pub const fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
25        Self {
26            x,
27            y,
28            width,
29            height,
30        }
31    }
32
33    /// Total area in cells (`width * height`).
34    #[inline]
35    pub const fn area(&self) -> u32 {
36        self.width * self.height
37    }
38
39    /// Exclusive right edge (`x + width`).
40    ///
41    /// This is one column past the last column in the rectangle.
42    #[inline]
43    pub const fn right(&self) -> u32 {
44        self.x + self.width
45    }
46
47    /// Exclusive bottom edge (`y + height`).
48    ///
49    /// This is one row past the last row in the rectangle.
50    #[inline]
51    pub const fn bottom(&self) -> u32 {
52        self.y + self.height
53    }
54
55    /// Returns `true` if the rectangle has zero area (width or height is zero).
56    #[inline]
57    pub const fn is_empty(&self) -> bool {
58        self.width == 0 || self.height == 0
59    }
60}