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}