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}