Skip to main content

ratatui_core/layout/
margin.rs

1use core::fmt;
2
3/// Represents spacing around rectangular areas.
4///
5/// `Margin` defines the horizontal and vertical spacing that should be applied around a rectangular
6/// area. It's commonly used with [`Layout`](crate::layout::Layout) to add space between the
7/// layout's boundaries and its contents, or with [`Rect::inner`](crate::layout::Rect::inner) and
8/// [`Rect::outer`](crate::layout::Rect::outer) to create padded areas.
9///
10/// The margin values represent the number of character cells to add on each side. For horizontal
11/// margin, the space is applied to both the left and right sides. For vertical margin, the space
12/// is applied to both the top and bottom sides.
13///
14/// # Construction
15///
16/// - [`new`](Self::new) - Create a new margin with horizontal and vertical spacing
17/// - [`default`](Default::default) - Create with zero margin
18///
19/// # Examples
20///
21/// ```rust
22/// use ratatui_core::layout::{Constraint, Layout, Margin, Rect};
23///
24/// // Create a margin of 2 cells horizontally and 1 cell vertically
25/// let margin = Margin::new(2, 1);
26///
27/// // Apply directly to a rectangle
28/// let area = Rect::new(0, 0, 80, 24);
29/// let inner_area = area.inner(margin);
30///
31/// // Or use with a layout (which only accepts uniform margins)
32/// let layout = Layout::vertical([Constraint::Fill(1)]).margin(2);
33/// ```
34///
35/// For comprehensive layout documentation and examples, see the [`layout`](crate::layout) module.
36#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash)]
37#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
38pub struct Margin {
39    pub horizontal: u16,
40    pub vertical: u16,
41}
42
43impl Margin {
44    pub const fn new(horizontal: u16, vertical: u16) -> Self {
45        Self {
46            horizontal,
47            vertical,
48        }
49    }
50}
51
52impl From<u16> for Margin {
53    fn from(value: u16) -> Self {
54        Self::new(value, value)
55    }
56}
57
58impl fmt::Display for Margin {
59    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60        write!(f, "{}x{}", self.horizontal, self.vertical)
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use alloc::string::ToString;
67
68    use super::*;
69
70    #[test]
71    fn margin_to_string() {
72        assert_eq!(Margin::new(1, 2).to_string(), "1x2");
73    }
74
75    #[test]
76    fn margin_new() {
77        assert_eq!(
78            Margin::new(1, 2),
79            Margin {
80                horizontal: 1,
81                vertical: 2
82            }
83        );
84    }
85
86    #[test]
87    fn from_u16() {
88        let m: Margin = 5_u16.into();
89        assert_eq!(
90            m,
91            Margin {
92                horizontal: 5,
93                vertical: 5
94            }
95        );
96    }
97}