1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//! Structures for working with styled text.

use std::ops::Deref;

use tui::text::{Span as TuiSpan, Spans as TuiSpans};

use crate::style::Style;

/// Text with a specific style.
#[derive(Default, Clone)]
pub struct Span {
  pub text: String,
  pub style: Style,
}

impl Span {
  pub fn new<Str: Into<String>, Sty: Into<Style>>(text: Str, style: Sty) -> Self {
    Self {
      text: text.into(),
      style: style.into(),
    }
  }
}

impl<S: Into<String>> From<S> for Span {
  fn from(s: S) -> Self {
    Self {
      text: s.into(),
      style: Style::default(),
    }
  }
}

impl<'a> From<&'a Span> for TuiSpan<'a> {
  fn from(span: &'a Span) -> Self {
    Self {
      content: (&span.text).into(),
      style: span.style.into(),
    }
  }
}

impl From<Span> for TuiSpan<'_> {
  fn from(span: Span) -> Self {
    Self {
      content: span.text.into(),
      style: span.style.into(),
    }
  }
}

/// Text with a variety of styles.
#[derive(Default, Clone)]
pub struct Spans(Vec<Span>);

impl Spans {
  pub fn new(spans: Vec<Span>) -> Self {
    Self(spans)
  }
}

impl From<Span> for Spans {
  fn from(span: Span) -> Self {
    Spans(vec![span])
  }
}

impl<S: Into<String>> From<S> for Spans {
  fn from(s: S) -> Self {
    Spans(vec![s.into().into()])
  }
}

impl<'a> From<&'a Spans> for TuiSpans<'a> {
  fn from(spans: &'a Spans) -> Self {
    TuiSpans(spans.0.iter().map(TuiSpan::from).collect())
  }
}

impl From<Spans> for TuiSpans<'_> {
  fn from(spans: Spans) -> Self {
    TuiSpans(spans.0.into_iter().map(TuiSpan::from).collect())
  }
}

impl IntoIterator for Spans {
  type Item = Span;
  type IntoIter = std::vec::IntoIter<Self::Item>;

  fn into_iter(self) -> Self::IntoIter {
    self.0.into_iter()
  }
}

impl Deref for Spans {
  type Target = Vec<Span>;

  fn deref(&self) -> &Self::Target {
    &self.0
  }
}