tui_markup/generator/ansi/
span.rs1use std::fmt::Display;
2
3use anstyle::{Color, Style};
4
5use crate::generator::{
6 Tag, TagConvertor,
7 helper::{FlattenableSpan, FlattenableStyle},
8};
9
10#[derive(Debug, Clone)]
18pub struct StyledSpan<'a> {
19 style: Style,
20 text: &'a str,
21}
22
23impl<'a> StyledSpan<'a> {
24 pub fn new(style: Style, text: &'a str) -> Self {
26 Self { style, text }
27 }
28
29 pub fn style(&self) -> &Style {
31 &self.style
32 }
33
34 pub fn text(&self) -> &'a str {
36 self.text
37 }
38}
39
40impl Display for StyledSpan<'_> {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 write!(f, "{}{}{:#}", self.style, self.text, self.style)
43 }
44}
45
46#[derive(Debug, Clone)]
52pub struct StyledText<'a> {
53 spans: Vec<StyledSpan<'a>>,
54}
55
56impl<'a> StyledText<'a> {
57 pub fn new(spans: Vec<StyledSpan<'a>>) -> Self {
59 Self { spans }
60 }
61
62 pub fn spans(&self) -> &[StyledSpan<'a>] {
64 &self.spans
65 }
66}
67
68impl Display for StyledText<'_> {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 for span in &self.spans {
71 Display::fmt(span, f)?;
72 }
73 Ok(())
74 }
75}
76
77impl<'a> From<Vec<StyledSpan<'a>>> for StyledText<'a> {
78 fn from(spans: Vec<StyledSpan<'a>>) -> Self {
79 Self::new(spans)
80 }
81}
82
83impl<'a, C> From<Tag<'a, C>> for Style
86where
87 C: TagConvertor<'a, Color = Color, Modifier = Style, Custom = Style>,
88{
89 fn from(t: Tag<'a, C>) -> Self {
90 match t {
91 Tag::Fg(c) => Self::new().fg_color(Some(c)),
92 Tag::Bg(c) => Self::new().bg_color(Some(c)),
93 Tag::Modifier(s) | Tag::Custom(s) => s,
94 }
95 }
96}
97
98impl FlattenableStyle for Style {
101 fn patch(self, other: Self) -> Self {
103 Self::new()
104 .fg_color(other.get_fg_color().or(self.get_fg_color()))
105 .bg_color(other.get_bg_color().or(self.get_bg_color()))
106 .effects(self.get_effects() | other.get_effects())
107 }
108}
109
110impl<'a> FlattenableSpan<'a, Style> for StyledSpan<'a> {
113 fn with_style(s: &'a str, style: Option<Style>) -> Self {
114 Self::new(style.unwrap_or_default(), s)
115 }
116}