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<E: Element> Element for Styled<E> {
23 fn width(&self) -> usize {
24 self.inner.width()
25 }
26
27 fn render(&self) -> impl DoubleEndedIterator<Item = RenderChunk<'_>> {
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::element::Text;
38
39 use super::*;
40
41 const STYLE_1: Style = Style {
42 foreground: Some(42),
43 ..Style::EMPTY
44 };
45
46 const STYLE_2: Style = Style {
47 foreground: Some(96),
48 ..Style::EMPTY
49 };
50
51 const STYLE_3: Style = Style {
52 background: Some(1),
53 ..Style::EMPTY
54 };
55
56 #[test]
57 fn basic() {
58 let element = Styled::new(STYLE_1, Text::from("Hello, world!"));
59 let render: Vec<_> = element.render().collect();
60 assert_eq!(render, [RenderChunk::new("Hello, world!", STYLE_1)]);
61 }
62
63 #[test]
64 fn nested() {
65 let element = Styled::new(STYLE_1, Styled::new(STYLE_2, Text::from("Hello, world!")));
66 let render: Vec<_> = element.render().collect();
67 assert_eq!(render, [RenderChunk::new("Hello, world!", STYLE_2)]);
68 }
69
70 #[test]
71 fn nested_merge() {
72 let element = Styled::new(STYLE_3, Styled::new(STYLE_2, Text::from("Hello, world!")));
73 let render: Vec<_> = element.render().collect();
74 assert_eq!(
75 render,
76 [RenderChunk::new(
77 "Hello, world!",
78 Style {
79 foreground: Some(96),
80 background: Some(1),
81 ..Style::EMPTY
82 },
83 )],
84 );
85 }
86}