modern_terminal/components/
text.rs1pub 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}