photon_ui/components/
truncated_text.rs1use crate::{
2 Component,
3 RenderError,
4 Rendered,
5 utils::truncate_to_width,
6};
7
8pub struct TruncatedText {
14 text: String,
15 pad_x: u16,
16 pad_y: u16,
17}
18
19impl TruncatedText {
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 TruncatedText {
31 fn render(&self, width: u16) -> Result<Rendered, RenderError> {
32 let mut lines = Vec::new();
33 for _ in 0..self.pad_y {
34 lines.push("".to_string());
35 }
36 let pad = " ".repeat(self.pad_x as usize);
37 let avail = width.saturating_sub(self.pad_x * 2);
38 for line in self.text.lines() {
39 let truncated = truncate_to_width(line, avail, "…");
40 lines.push(format!("{}{}", pad, truncated));
41 }
42 for _ in 0..self.pad_y {
43 lines.push("".to_string());
44 }
45 Ok(Rendered {
46 lines,
47 cursor: None,
48 images: Vec::new(),
49 })
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn truncated_text_with_padding() {
59 let t = TruncatedText::new("hello", 2, 1);
60 let r = t.render(20).unwrap();
61 assert_eq!(r.lines.len(), 3); assert!(r.lines[0].is_empty());
63 assert!(r.lines[1].starts_with(" hello"));
64 assert!(r.lines[2].is_empty());
65 }
66
67 #[test]
68 fn truncated_text_empty_with_padding() {
69 let t = TruncatedText::new("", 0, 2);
70 let r = t.render(10).unwrap();
71 assert_eq!(r.lines.len(), 4);
72 }
73}