paris/formatter/
icons.rs

1//! Contains icons that can be used when
2//! outputting to the terminal. All icons are printable
3//! and can be converted to strings.
4//!
5//! There are no tags that can be used
6//! in log strings on the other hand. So you can't
7//! write `<info>` in a string and expect it to
8//! be replaced with the info icon.
9use super::keys::FromKey;
10use std::fmt::{Display, Formatter, Result as DisplayResult};
11use std::str::FromStr;
12
13/// Contains definitions for icons that can be
14/// used in the terminal. See [this github repo](https://github.com/sindresorhus/figures)
15/// for an entire list. Use this in combination with printing macros.
16pub enum LogIcon {
17    /// A check mark, use when things go well
18    ///
19    /// # Example
20    /// ```
21    /// use paris::LogIcon;
22    ///
23    /// println!("{} Everything went well", LogIcon::Tick);
24    /// // ✔ Everything went well
25    /// ```
26    Tick,
27
28    /// A cross, use when things go bad, or be creative
29    ///
30    /// # Example
31    /// ```
32    /// # use paris::LogIcon;
33    /// println!("{} Oops, try again!", LogIcon::Cross);
34    /// // ✖ Oops, try again!
35    /// ```
36    Cross,
37
38    /// A fancy 'i', for information
39    ///
40    /// # Example
41    /// ```
42    /// # use paris::LogIcon;
43    /// println!("{} In Switzerland it is illegal to own just one guinea pig", LogIcon::Info);
44    /// // ℹ In Switzerland it is illegal to own just one guinea pig.
45    /// ```
46    Info,
47
48    /// A triangle with an exclamation mark in it, dangerous
49    ///
50    /// # Example
51    /// ```
52    /// # use paris::LogIcon;
53    /// println!("{} Things are starting to catch fire!", LogIcon::Warning);
54    /// // ⚠ Things are starting to catch fire!
55    /// ```
56    Warning,
57
58    /// ❤️🦄
59    /// # Example
60    /// ```
61    /// // You get it...
62    /// ```
63    Heart,
64
65    /// No icon. Empty string. Nada.
66    /// This is here to return something
67    /// for the parser when it doesn't match
68    /// any given keys
69    None,
70}
71
72impl LogIcon {
73    /// Match the enum value and return the equivalent icon.
74    /// See [this github repo](https://github.com/sindresorhus/figures)
75    /// for all icons
76    pub fn to_str<'a>(&self) -> &'a str {
77        match self {
78            LogIcon::Info => "ℹ",
79            LogIcon::Cross => "✖",
80            LogIcon::Warning => "⚠",
81            LogIcon::Tick => "✔",
82            LogIcon::Heart => "♥",
83            LogIcon::None => "",
84        }
85    }
86}
87
88impl Display for LogIcon {
89    fn fmt(&self, f: &mut Formatter<'_>) -> DisplayResult {
90        write!(f, "{}", self.to_str())
91    }
92}
93
94impl<'a> From<&'a str> for LogIcon {
95    fn from(s: &'a str) -> Self {
96        s.parse().unwrap_or(LogIcon::None)
97    }
98}
99
100impl FromStr for LogIcon {
101    type Err = ();
102
103    fn from_str(s: &str) -> Result<Self, Self::Err> {
104        let s = s.to_lowercase();
105
106        match s.as_ref() {
107            "info" => Ok(LogIcon::Info),
108            "cross" => Ok(LogIcon::Cross),
109            "warn" => Ok(LogIcon::Warning),
110            "tick" => Ok(LogIcon::Tick),
111            "heart" => Ok(LogIcon::Heart),
112            _ => Err(()),
113        }
114    }
115}
116
117impl FromKey for LogIcon {
118    fn from_key(key: &str) -> Option<String> {
119        let i = LogIcon::from(key);
120
121        match i {
122            LogIcon::None => None,
123            _ => Some(i.to_string()),
124        }
125    }
126}
127
128#[cfg(test)]
129mod tests {
130    use super::*;
131
132    macro_rules! icon_test {
133        ($name:ident, $value:expr) => {
134            #[test]
135            fn $name() {
136                let v = String::from(stringify!($name));
137                let c = LogIcon::from_key(&v).unwrap();
138
139                assert_eq!(c, $value);
140            }
141        };
142    }
143
144    icon_test!(tick, "✔");
145    icon_test!(cross, "✖");
146    icon_test!(info, "ℹ");
147    icon_test!(warn, "⚠");
148    icon_test!(heart, "♥");
149}