1use std::{
2 borrow::Cow,
3 fmt::{self, Write},
4};
5
6use super::{Color, StaticColor};
7
8/// The structure represents a ANSI color by suffix and prefix.
9#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
10pub struct AnsiColor<'a> {
11 prefix: Cow<'a, str>,
12 suffix: Cow<'a, str>,
13}
14
15impl<'a> AnsiColor<'a> {
16 /// Constructs a new instance with suffix and prefix.
17 ///
18 /// They are not checked so you should make sure you provide correct ANSI.
19 /// Otherwise you may want to use [`TryFrom`].
20 ///
21 /// [`TryFrom`]: std::convert::TryFrom
22 pub const fn new(prefix: Cow<'a, str>, suffix: Cow<'a, str>) -> Self {
23 Self { prefix, suffix }
24 }
25}
26
27impl AnsiColor<'_> {
28 /// Gets a reference to a prefix.
29 pub fn get_prefix(&self) -> &str {
30 &self.prefix
31 }
32
33 /// Gets a reference to a suffix.
34 pub fn get_suffix(&self) -> &str {
35 &self.suffix
36 }
37}
38
39impl Color for AnsiColor<'_> {
40 fn fmt_prefix<W: Write>(&self, f: &mut W) -> fmt::Result {
41 f.write_str(&self.prefix)
42 }
43
44 fn fmt_suffix<W: Write>(&self, f: &mut W) -> fmt::Result {
45 f.write_str(&self.suffix)
46 }
47}
48
49#[cfg(feature = "color")]
50impl std::convert::TryFrom<&str> for AnsiColor<'static> {
51 type Error = ();
52
53 fn try_from(value: &str) -> Result<Self, Self::Error> {
54 parse_ansi_color(value).ok_or(())
55 }
56}
57
58#[cfg(feature = "color")]
59impl std::convert::TryFrom<String> for AnsiColor<'static> {
60 type Error = ();
61
62 fn try_from(value: String) -> Result<Self, Self::Error> {
63 Self::try_from(value.as_str())
64 }
65}
66
67#[cfg(feature = "color")]
68fn parse_ansi_color(s: &str) -> Option<AnsiColor<'static>> {
69 let mut blocks = ansi_str::get_blocks(s);
70 let block = blocks.next()?;
71 let style = block.style();
72
73 let start = style.start().to_string();
74 let end = style.end().to_string();
75
76 Some(AnsiColor::new(start.into(), end.into()))
77}
78
79impl From<StaticColor> for AnsiColor<'static> {
80 fn from(value: StaticColor) -> Self {
81 Self::new(
82 prefix:Cow::Borrowed(value.get_prefix()),
83 suffix:Cow::Borrowed(value.get_suffix()),
84 )
85 }
86}
87