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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
//! Contains icons that can be used when
//! outputting to the terminal. All icons are printable
//! and can be converted to strings.
//!
//! There are no tags that can be used
//! in log strings on the other hand. So you can't
//! write `<info>` in a string and expect it to
//! be replaced with the info icon.
use super::keys::FromKey;
use std::fmt::{Display, Formatter, Result as DisplayResult};
use std::str::FromStr;
/// Contains definitions for icons that can be
/// used in the terminal. See [this github repo](https://github.com/sindresorhus/figures)
/// for an entire list. Use this in combination with printing macros.
pub enum LogIcon {
/// A check mark, use when things go well
///
/// # Example
/// ```
/// use paris::LogIcon;
///
/// println!("{} Everything went well", LogIcon::Tick);
/// // ✔ Everything went well
/// ```
Tick,
/// A cross, use when things go bad, or be creative
///
/// # Example
/// ```
/// # use paris::LogIcon;
/// println!("{} Oops, try again!", LogIcon::Cross);
/// // ✖ Oops, try again!
/// ```
Cross,
/// A fancy 'i', for information
///
/// # Example
/// ```
/// # use paris::LogIcon;
/// println!("{} In Switzerland it is illegal to own just one guinea pig", LogIcon::Info);
/// // ℹ In Switzerland it is illegal to own just one guinea pig.
/// ```
Info,
/// A triangle with an exclamation mark in it, dangerous
///
/// # Example
/// ```
/// # use paris::LogIcon;
/// println!("{} Things are starting to catch fire!", LogIcon::Warning);
/// // ⚠ Things are starting to catch fire!
/// ```
Warning,
/// ❤️🦄
/// # Example
/// ```
/// // You get it...
/// ```
Heart,
/// No icon. Empty string. Nada.
/// This is here to return something
/// for the parser when it doesn't match
/// any given keys
None,
}
impl LogIcon {
/// Match the enum value and return the equivalent icon.
/// See [this github repo](https://github.com/sindresorhus/figures)
/// for all icons
pub fn to_str<'a>(&self) -> &'a str {
match self {
LogIcon::Info => "ℹ",
LogIcon::Cross => "✖",
LogIcon::Warning => "⚠",
LogIcon::Tick => "✔",
LogIcon::Heart => "♥",
LogIcon::None => "",
}
}
}
impl Display for LogIcon {
fn fmt(&self, f: &mut Formatter<'_>) -> DisplayResult {
write!(f, "{}", self.to_str())
}
}
impl<'a> From<&'a str> for LogIcon {
fn from(s: &'a str) -> Self {
s.parse().unwrap_or(LogIcon::None)
}
}
impl FromStr for LogIcon {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
let s = s.to_lowercase();
match s.as_ref() {
"info" => Ok(LogIcon::Info),
"cross" => Ok(LogIcon::Cross),
"warn" => Ok(LogIcon::Warning),
"tick" => Ok(LogIcon::Tick),
"heart" => Ok(LogIcon::Heart),
_ => Err(()),
}
}
}
impl FromKey for LogIcon {
fn from_key(key: &str) -> Option<String> {
let i = LogIcon::from(key);
match i {
LogIcon::None => None,
_ => Some(i.to_string()),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
macro_rules! icon_test {
($name:ident, $value:expr) => {
#[test]
fn $name() {
let v = String::from(stringify!($name));
let c = LogIcon::from_key(&v).unwrap();
assert_eq!(c, $value);
}
};
}
icon_test!(tick, "✔");
icon_test!(cross, "✖");
icon_test!(info, "ℹ");
icon_test!(warn, "⚠");
icon_test!(heart, "♥");
}