Skip to main content

uncurses/layout/
position.rs

1//! [`Position`] — a point in the cell grid.
2
3use core::fmt;
4
5use super::Rect;
6
7/// A point in the cell grid (`x` column, `y` row).
8#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
9pub struct Position {
10    /// Column (0-based, increases to the right).
11    pub x: u16,
12    /// Row (0-based, increases downward).
13    pub y: u16,
14}
15
16impl Position {
17    /// The top-left corner of the grid.
18    pub const ORIGIN: Self = Self::new(0, 0);
19
20    /// Create a position from `(x, y)`.
21    pub const fn new(x: u16, y: u16) -> Self {
22        Self { x, y }
23    }
24}
25
26impl From<(u16, u16)> for Position {
27    fn from((x, y): (u16, u16)) -> Self {
28        Self { x, y }
29    }
30}
31
32impl From<Position> for (u16, u16) {
33    fn from(p: Position) -> Self {
34        (p.x, p.y)
35    }
36}
37
38impl From<Rect> for Position {
39    /// The top-left corner of the rectangle.
40    fn from(r: Rect) -> Self {
41        Self { x: r.x, y: r.y }
42    }
43}
44
45impl fmt::Display for Position {
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        write!(f, "({}, {})", self.x, self.y)
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn position_from_tuple() {
57        let p: Position = (3, 5).into();
58        assert_eq!(p, Position::new(3, 5));
59        let (x, y): (u16, u16) = p.into();
60        assert_eq!((x, y), (3, 5));
61    }
62
63    #[test]
64    fn position_from_rect() {
65        let r = Rect::new(7, 9, 1, 1);
66        assert_eq!(Position::from(r), Position::new(7, 9));
67    }
68}