line_ui/element/
styled.rs1use crate::element::Element;
6use crate::render::RenderChunk;
7use crate::style::Style;
8
9pub struct Styled<E> {
11 style: Style,
12 inner: E,
13}
14
15impl<E> Styled<E> {
16 pub fn new(style: Style, inner: E) -> Self {
18 Styled { style, inner }
19 }
20}
21
22impl<'s, E: Element<'s>> Element<'s> for Styled<E> {
23 fn width(&self) -> usize {
24 self.inner.width()
25 }
26
27 fn render(&self) -> impl DoubleEndedIterator<Item = RenderChunk<'s>> {
28 self.inner.render().map(|mut item| {
29 item.style = item.style.or(self.style);
30 item
31 })
32 }
33}
34
35#[cfg(test)]
36mod tests {
37 use crate::Color;
38 use crate::element::Text;
39
40 use super::*;
41
42 const STYLE_1: Style = Style {
43 foreground: Some(Color::Ansi(42)),
44 ..Style::EMPTY
45 };
46
47 const STYLE_2: Style = Style {
48 foreground: Some(Color::Ansi(96)),
49 ..Style::EMPTY
50 };
51
52 const STYLE_3: Style = Style {
53 background: Some(Color::Ansi(1)),
54 ..Style::EMPTY
55 };
56
57 #[test]
58 fn basic() {
59 let element = Styled::new(STYLE_1, Text::from("Hello, world!"));
60 let render: Vec<_> = element.render().collect();
61 assert_eq!(render, [RenderChunk::new("Hello, world!", STYLE_1)]);
62 }
63
64 #[test]
65 fn nested() {
66 let element = Styled::new(STYLE_1, Styled::new(STYLE_2, Text::from("Hello, world!")));
67 let render: Vec<_> = element.render().collect();
68 assert_eq!(render, [RenderChunk::new("Hello, world!", STYLE_2)]);
69 }
70
71 #[test]
72 fn nested_merge() {
73 let element = Styled::new(STYLE_3, Styled::new(STYLE_2, Text::from("Hello, world!")));
74 let render: Vec<_> = element.render().collect();
75 assert_eq!(
76 render,
77 [RenderChunk::new(
78 "Hello, world!",
79 Style {
80 foreground: Some(96.into()),
81 background: Some(1.into()),
82 ..Style::EMPTY
83 },
84 )],
85 );
86 }
87}