modern_terminal/components/
text.rs

1pub enum TextAlignment {
2    Center,
3    Left,
4    Right,
5}
6
7pub struct Text {
8    pub align:  TextAlignment,
9    pub styles: Vec<crate::core::style::Style>,
10    pub text:   String,
11}
12
13impl crate::core::render::Render for Text {
14    fn render(
15        &self,
16        options: &crate::core::render::Options,
17    ) -> crate::core::segment::RenderedSegments {
18        let columns = match options.columns {
19            Some(columns) => columns,
20            None => crate::core::render::DEFAULT_COLUMNS,
21        };
22
23        let mut rendered_segments = Vec::new();
24
25        for line in wrap(&self.text, columns, options.rows) {
26            let mut segment = crate::core::segment::Segment::new();
27            for style in self.styles.iter() {
28                segment.add_style(style.clone());
29            }
30            segment.add_text(&line);
31            rendered_segments.push(segment.render(
32                match self.align {
33                    TextAlignment::Center => {
34                        crate::core::segment::SegmentPadding::Center(columns)
35                    },
36                    TextAlignment::Left => {
37                        crate::core::segment::SegmentPadding::Left(columns)
38                    },
39                    TextAlignment::Right => {
40                        crate::core::segment::SegmentPadding::Right(columns)
41                    },
42                },
43                options.storage,
44            ));
45        }
46
47        rendered_segments
48    }
49}
50
51fn wrap(
52    text: &str,
53    columns: usize,
54    rows: Option<usize>,
55) -> Vec<String> {
56    let mut lines = Vec::new();
57
58    for line in &mut textwrap::wrap(text, columns) {
59        let line = String::from(match line {
60            std::borrow::Cow::Borrowed(line) => *line,
61            std::borrow::Cow::Owned(line) => line,
62        });
63        match rows {
64            Some(rows) => {
65                if lines.len() < rows {
66                    lines.push(line);
67                }
68            },
69            None => {
70                lines.push(line);
71            },
72        };
73    }
74
75    lines
76}
77
78#[cfg(test)]
79mod tests {
80    use super::wrap;
81
82    #[test]
83    fn test_wrap() {
84        let text = "0123456789 01234 56789 012";
85
86        assert_eq!(wrap(text, 4, Some(7)), vec![
87            "0123", "4567", "89", "0123", "4", "5678", "9"
88        ],);
89        assert_eq!(wrap(text, 4, None), vec![
90            "0123", "4567", "89", "0123", "4", "5678", "9", "012"
91        ],);
92    }
93}