1#![no_std]
8#![warn(missing_docs)]
9#![deny(unsafe_code)]
10
11#[cfg(feature = "alloc")]
12extern crate alloc;
13
14pub mod decode;
16
17pub mod encode;
19
20#[cfg(test)]
22pub mod tests;
23
24use bitflags::bitflags;
25
26pub const START: char = '\x01';
28
29pub const END: char = '\x02';
31
32pub const STYLE_LEN: usize = 5;
36
37pub const DESCRIPTOR_LEN: usize = 3;
41
42#[cfg(feature = "alloc")]
46#[derive(Clone, Eq, PartialEq, Debug, Default)]
47pub struct Span {
48 pub text: alloc::string::String,
50 pub style: Style,
52}
53
54#[cfg(feature = "alloc")]
55impl Span {
56 pub const fn new(text: alloc::string::String, style: Style) -> Self {
58 Self { text, style }
59 }
60
61 pub fn with_text(mut self, text: alloc::string::String) -> Self {
63 self.text = text;
64 self
65 }
66
67 pub const fn with_style(mut self, style: Style) -> Self {
69 self.style = style;
70 self
71 }
72}
73
74#[derive(Copy, Clone, Default, Eq, PartialEq, Debug)]
76pub struct Style {
77 pub foreground: Color,
79 pub background: Color,
81 pub attributes: Attributes,
83}
84
85impl Style {
86 pub const fn new(foreground: Color, background: Color, attributes: Attributes) -> Self {
88 Self {
89 foreground,
90 background,
91 attributes,
92 }
93 }
94
95 pub const fn with_foreground(mut self, foreground: Color) -> Self {
97 self.foreground = foreground;
98 self
99 }
100
101 pub const fn with_background(mut self, background: Color) -> Self {
103 self.background = background;
104 self
105 }
106
107 pub const fn with_attribute(mut self, attributes: Attributes) -> Self {
109 self.attributes = attributes;
110 self
111 }
112}
113
114#[repr(u8)]
136#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
137pub enum Color {
138 #[default]
140 None = 0,
141 Gray = 1,
143 BrightGray = 2,
145 BrighterGray = 3,
147 DarkGray = 4,
149 DarkerGray = 5,
151 Red = 6,
153 BrightRed = 7,
155 BrighterRed = 8,
157 DarkRed = 9,
159 DarkerRed = 10,
161 Green = 11,
163 BrightGreen = 12,
165 BrighterGreen = 13,
167 DarkGreen = 14,
169 DarkerGreen = 15,
171 Yellow = 16,
173 BrightYellow = 17,
175 BrighterYellow = 18,
177 DarkYellow = 19,
179 DarkerYellow = 20,
181 Blue = 21,
183 BrightBlue = 22,
185 BrighterBlue = 23,
187 DarkBlue = 24,
189 DarkerBlue = 25,
191 Purple = 26,
193 BrightPurple = 27,
195 BrighterPurple = 28,
197 DarkPurple = 29,
199 DarkerPurple = 30,
201 Cyan = 31,
203 BrightCyan = 32,
205 BrighterCyan = 33,
207 DarkCyan = 34,
209 DarkerCyan = 35,
211}
212
213impl Color {
214 pub const fn parse(byte: u8) -> Option<Self> {
218 match byte {
219 0 => Some(Color::None),
220 1 => Some(Color::Gray),
221 2 => Some(Color::BrightGray),
222 3 => Some(Color::BrighterGray),
223 4 => Some(Color::DarkGray),
224 5 => Some(Color::DarkerGray),
225 6 => Some(Color::Red),
226 7 => Some(Color::BrightRed),
227 8 => Some(Color::BrighterRed),
228 9 => Some(Color::DarkRed),
229 10 => Some(Color::DarkerRed),
230 11 => Some(Color::Green),
231 12 => Some(Color::BrightGreen),
232 13 => Some(Color::BrighterGreen),
233 14 => Some(Color::DarkGreen),
234 15 => Some(Color::DarkerGreen),
235 16 => Some(Color::Yellow),
236 17 => Some(Color::BrightYellow),
237 18 => Some(Color::BrighterYellow),
238 19 => Some(Color::DarkYellow),
239 20 => Some(Color::DarkerYellow),
240 21 => Some(Color::Blue),
241 22 => Some(Color::BrightBlue),
242 23 => Some(Color::BrighterBlue),
243 24 => Some(Color::DarkBlue),
244 25 => Some(Color::DarkerBlue),
245 26 => Some(Color::Purple),
246 27 => Some(Color::BrightPurple),
247 28 => Some(Color::BrighterPurple),
248 29 => Some(Color::DarkPurple),
249 30 => Some(Color::DarkerPurple),
250 31 => Some(Color::Cyan),
251 32 => Some(Color::BrightCyan),
252 33 => Some(Color::BrighterCyan),
253 34 => Some(Color::DarkCyan),
254 35 => Some(Color::DarkerCyan),
255 _ => None,
256 }
257 }
258
259 pub const fn to_byte(&self) -> u8 {
261 *self as u8
262 }
263
264 pub const fn to_rgb(&self) -> Option<(u8, u8, u8)> {
268 match self {
269 Color::None => None,
270 Color::Gray => Some((128, 128, 128)),
271 Color::BrightGray => Some((192, 192, 192)),
272 Color::BrighterGray => Some((255, 255, 255)),
273 Color::DarkGray => Some((64, 64, 64)),
274 Color::DarkerGray => Some((0, 0, 0)),
275 Color::Red => Some((255, 0, 0)),
276 Color::BrightRed => Some((255, 64, 64)),
277 Color::BrighterRed => Some((255, 128, 128)),
278 Color::DarkRed => Some((128, 0, 0)),
279 Color::DarkerRed => Some((64, 0, 0)),
280 Color::Green => Some((0, 255, 0)),
281 Color::BrightGreen => Some((64, 255, 64)),
282 Color::BrighterGreen => Some((128, 255, 128)),
283 Color::DarkGreen => Some((0, 128, 0)),
284 Color::DarkerGreen => Some((0, 64, 0)),
285 Color::Yellow => Some((255, 255, 0)),
286 Color::BrightYellow => Some((255, 255, 64)),
287 Color::BrighterYellow => Some((255, 255, 128)),
288 Color::DarkYellow => Some((128, 128, 0)),
289 Color::DarkerYellow => Some((64, 64, 0)),
290 Color::Blue => Some((0, 0, 255)),
291 Color::BrightBlue => Some((64, 64, 255)),
292 Color::BrighterBlue => Some((128, 128, 255)),
293 Color::DarkBlue => Some((0, 0, 128)),
294 Color::DarkerBlue => Some((0, 0, 64)),
295 Color::Purple => Some((128, 0, 128)),
296 Color::BrightPurple => Some((192, 64, 192)),
297 Color::BrighterPurple => Some((224, 128, 224)),
298 Color::DarkPurple => Some((64, 0, 64)),
299 Color::DarkerPurple => Some((32, 0, 32)),
300 Color::Cyan => Some((0, 255, 255)),
301 Color::BrightCyan => Some((64, 255, 255)),
302 Color::BrighterCyan => Some((128, 255, 255)),
303 Color::DarkCyan => Some((0, 128, 128)),
304 Color::DarkerCyan => Some((0, 64, 64)),
305 }
306 }
307}
308
309bitflags! {
310 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
319 pub struct Attributes: u8 {
320 const BOLD = 1;
322 const ITALIC = 1 << 1;
324 const UNDERLINE = 1 << 2;
326 const STRIKETHROUGH = 1 << 3;
328 const HIDDEN = 1 << 4;
330 }
331}
332
333impl Attributes {
334 pub const fn parse(byte: u8) -> Option<Self> {
338 Self::from_bits(byte)
339 }
340
341 pub const fn to_byte(&self) -> u8 {
343 self.bits()
344 }
345}