1#![no_std]
16
17use core::fmt;
18use core::fmt::Display;
19use core::ops::{Deref, DerefMut};
20
21use ansi_term::Style;
22
23pub use ansi_term::Color;
26
27#[derive(Debug, Clone, Copy, PartialEq)]
29pub struct Styled<T> {
30 inner: T,
31 style: Style,
32}
33
34macro_rules! meth_color {
35 ($meth:ident, $color:ident) => {
36 pub fn $meth(self) -> Self {
37 self.fg(Color::$color)
38 }
39 };
40 ($meth:ident, $color:ident($($arg:ident),+)) => {
41 pub fn $meth(self, $($arg: u8),+) -> Self {
42 self.fg(Color::$color($($arg),+))
43 }
44 };
45}
46
47macro_rules! meth_style {
48 ($meth:ident) => {
49 pub fn $meth(self) -> Self {
50 let Self { inner, style } = self;
51 Self {
52 inner,
53 style: style.$meth(),
54 }
55 }
56 };
57 ($meth:ident, $color:ident) => {
58 pub fn $meth(self, $color: Color) -> Self {
59 let Self { inner, style } = self;
60 Self {
61 inner,
62 style: style.$meth($color),
63 }
64 }
65 };
66}
67
68impl<T> Styled<T> {
69 fn new(inner: T) -> Self {
71 Self {
72 inner,
73 style: Style::new(),
74 }
75 }
76
77 meth_style!(bold);
79 meth_style!(dimmed);
80 meth_style!(italic);
81 meth_style!(underline);
82 meth_style!(blink);
83 meth_style!(reverse);
84 meth_style!(hidden);
85 meth_style!(strikethrough);
86 meth_style!(fg, color);
87 meth_style!(on, color);
88
89 meth_color!(black, Black);
91 meth_color!(red, Red);
92 meth_color!(green, Green);
93 meth_color!(yellow, Yellow);
94 meth_color!(blue, Blue);
95 meth_color!(magenta, Purple);
96 meth_color!(cyan, Cyan);
97 meth_color!(white, White);
98 meth_color!(fixed, Fixed(n));
99 meth_color!(rgb, RGB(r, g, b));
100}
101
102impl<T> Deref for Styled<T> {
103 type Target = T;
104
105 fn deref(&self) -> &Self::Target {
106 &self.inner
107 }
108}
109
110impl<T> DerefMut for Styled<T> {
111 fn deref_mut(&mut self) -> &mut Self::Target {
112 &mut self.inner
113 }
114}
115
116impl<T: Display> Display for Styled<T> {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 write!(f, "{}", self.style.prefix())?;
119 Display::fmt(&self.inner, f)?;
120 write!(f, "{}", self.style.suffix())?;
121 Ok(())
122 }
123}
124
125macro_rules! meth_color {
126 ($meth:ident, $color:ident) => {
127 fn $meth(&self) -> Styled<&Self> {
128 self.fg(Color::$color)
129 }
130 };
131 ($meth:ident, $color:ident($($arg:ident),+)) => {
132 fn $meth(&self, $($arg: u8),+) -> Styled<&Self> {
133 self.fg(Color::$color($($arg),+))
134 }
135 };
136}
137
138macro_rules! meth_style {
139 ($meth:ident) => {
140 fn $meth(&self) -> Styled<&Self> {
141 Styled::new(self).$meth()
142 }
143 };
144 ($meth:ident, $color:ident) => {
145 fn $meth(&self, $color: Color) -> Styled<&Self> {
146 Styled::new(self).$meth($color)
147 }
148 };
149}
150
151pub trait Stylize<T>: Sized {
153 meth_style!(bold);
155 meth_style!(dimmed);
156 meth_style!(italic);
157 meth_style!(underline);
158 meth_style!(blink);
159 meth_style!(reverse);
160 meth_style!(hidden);
161 meth_style!(strikethrough);
162 meth_style!(fg, color);
163 meth_style!(on, color);
164
165 meth_color!(black, Black);
167 meth_color!(red, Red);
168 meth_color!(green, Green);
169 meth_color!(yellow, Yellow);
170 meth_color!(blue, Blue);
171 meth_color!(magenta, Purple);
172 meth_color!(cyan, Cyan);
173 meth_color!(white, White);
174 meth_color!(fixed, Fixed(n));
175 meth_color!(rgb, RGB(r, g, b));
176}
177
178impl<T> Stylize<T> for T where T: Display {}