tari_log4rs/encode/writer/
ansi.rs1use crate::encode::{self, Color, Style};
6use std::{fmt, io};
7
8#[derive(Clone, Eq, PartialEq, Hash, Debug)]
11pub struct AnsiWriter<W>(pub W);
12
13impl<W: io::Write> io::Write for AnsiWriter<W> {
14 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
15 self.0.write(buf)
16 }
17
18 fn flush(&mut self) -> io::Result<()> {
19 self.0.flush()
20 }
21
22 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
23 self.0.write_all(buf)
24 }
25
26 fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
27 self.0.write_fmt(fmt)
28 }
29}
30
31impl<W: io::Write> encode::Write for AnsiWriter<W> {
32 fn set_style(&mut self, style: &Style) -> io::Result<()> {
33 let mut buf = [0; 12];
34 buf[0] = b'\x1b';
35 buf[1] = b'[';
36 buf[2] = b'0';
37 let mut idx = 3;
38
39 if let Some(text) = style.text {
40 buf[idx] = b';';
41 buf[idx + 1] = b'3';
42 buf[idx + 2] = color_byte(text);
43 idx += 3;
44 }
45
46 if let Some(background) = style.background {
47 buf[idx] = b';';
48 buf[idx + 1] = b'4';
49 buf[idx + 2] = color_byte(background);
50 idx += 3;
51 }
52
53 if let Some(intense) = style.intense {
54 buf[idx] = b';';
55 if intense {
56 buf[idx + 1] = b'1';
57 idx += 2;
58 } else {
59 buf[idx + 1] = b'2';
60 buf[idx + 2] = b'2';
61 idx += 3;
62 }
63 }
64 buf[idx] = b'm';
65 self.0.write_all(&buf[..=idx])
66 }
67}
68
69fn color_byte(c: Color) -> u8 {
70 match c {
71 Color::Black => b'0',
72 Color::Red => b'1',
73 Color::Green => b'2',
74 Color::Yellow => b'3',
75 Color::Blue => b'4',
76 Color::Magenta => b'5',
77 Color::Cyan => b'6',
78 Color::White => b'7',
79 }
80}
81
82#[cfg(test)]
83mod test {
84 use std::io::{self, Write};
85
86 use super::*;
87 use crate::encode::{Color, Style, Write as EncodeWrite};
88
89 #[test]
90 fn basic() {
91 let stdout = io::stdout();
92 let mut w = AnsiWriter(stdout.lock());
93
94 w.write_all(b"normal ").unwrap();
95 w.set_style(
96 Style::new()
97 .text(Color::Red)
98 .background(Color::Blue)
99 .intense(true),
100 )
101 .unwrap();
102 w.write_all(b"styled").unwrap();
103 w.set_style(Style::new().text(Color::Green)).unwrap();
104 w.write_all(b" styled2").unwrap();
105 w.set_style(&Style::new()).unwrap();
106 w.write_all(b" normal\n").unwrap();
107 w.flush().unwrap();
108 }
109}