photon_ui/components/
text.rs1use crate::{
2 Component,
3 RenderError,
4 Rendered,
5};
6
7pub struct Text {
14 text: String,
15 pad_x: u16,
16 pad_y: u16,
17}
18
19impl Text {
20 pub fn new(text: impl Into<String>, pad_x: u16, pad_y: u16) -> Self {
22 Self {
23 text: text.into(),
24 pad_x,
25 pad_y,
26 }
27 }
28}
29
30impl Component for Text {
31 fn render(&self, width: u16) -> Result<Rendered, RenderError> {
32 let mut lines = Vec::new();
33 let empty_line = " ".repeat(width as usize);
34 for _ in 0..self.pad_y {
35 lines.push(empty_line.clone());
36 }
37 let pad = " ".repeat(self.pad_x as usize);
38 for line in self.text.lines() {
39 let padded = format!("{}{}", pad, line);
40 let truncated = crate::utils::truncate_to_width(&padded, width, "…");
41 let vw = crate::utils::visible_width(&truncated);
42 let mut final_line = truncated;
43 if vw < width as usize {
44 final_line.push_str(&" ".repeat(width as usize - vw));
45 }
46 lines.push(final_line);
47 }
48 for _ in 0..self.pad_y {
49 lines.push(empty_line.clone());
50 }
51 Ok(Rendered {
52 lines,
53 cursor: None,
54 images: Vec::new(),
55 })
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn text_truncates_to_width() {
65 let text = Text::new("hello world", 0, 0);
66 let rendered = text.render(5).unwrap();
67 assert_eq!(rendered.lines.len(), 1);
68 assert_eq!(rendered.lines[0].trim_end(), "hell…"); }
70
71 #[test]
72 fn text_pads_to_width() {
73 let text = Text::new("hi", 0, 0);
74 let rendered = text.render(10).unwrap();
75 assert_eq!(rendered.lines.len(), 1);
76 assert_eq!(rendered.lines[0].len(), 10);
77 assert_eq!(rendered.lines[0], "hi ");
78 }
79
80 #[test]
81 fn text_pad_y_adds_blank_lines() {
82 let text = Text::new("a", 0, 2);
83 let rendered = text.render(10).unwrap();
84 assert_eq!(rendered.lines.len(), 5); assert_eq!(rendered.lines[0], " "); assert_eq!(rendered.lines[1], " ");
87 assert!(rendered.lines[2].starts_with("a"));
88 assert_eq!(rendered.lines[3], " ");
89 assert_eq!(rendered.lines[4], " ");
90 }
91
92 #[test]
93 fn text_pad_x_prefixes_spaces() {
94 let text = Text::new("x", 3, 0);
95 let rendered = text.render(10).unwrap();
96 assert_eq!(rendered.lines[0], " x "); }
98
99 #[test]
100 fn text_long_line_with_pad_x_truncates() {
101 let text = Text::new("abcdefghij", 5, 0);
102 let rendered = text.render(10).unwrap();
103 assert!(rendered.lines[0].starts_with(" ")); assert!(rendered.lines[0].trim_end().ends_with("abcd…"));
106 }
107}