flywheel/terminal/
output.rs1use crate::buffer::Rgb;
4use std::io::Write;
5
6pub struct OutputBuffer {
11 data: Vec<u8>,
12}
13
14impl OutputBuffer {
15 pub fn with_capacity(capacity: usize) -> Self {
17 Self {
18 data: Vec::with_capacity(capacity),
19 }
20 }
21
22 pub fn new() -> Self {
24 Self::with_capacity(4096)
25 }
26
27 #[inline]
29 pub fn clear(&mut self) {
30 self.data.clear();
31 }
32
33 #[inline]
35 pub fn as_bytes(&self) -> &[u8] {
36 &self.data
37 }
38
39 #[inline]
41 pub const fn len(&self) -> usize {
42 self.data.len()
43 }
44
45 #[inline]
47 pub const fn is_empty(&self) -> bool {
48 self.data.is_empty()
49 }
50
51 #[inline]
53 pub fn write_raw(&mut self, bytes: &[u8]) {
54 self.data.extend_from_slice(bytes);
55 }
56
57 #[inline]
59 pub fn write_str(&mut self, s: &str) {
60 self.data.extend_from_slice(s.as_bytes());
61 }
62
63 #[inline]
65 pub fn cursor_move(&mut self, x: u16, y: u16) {
66 write!(self.data, "\x1b[{};{}H", y + 1, x + 1).unwrap();
68 }
69
70 #[inline]
72 pub fn cursor_hide(&mut self) {
73 self.data.extend_from_slice(b"\x1b[?25l");
74 }
75
76 #[inline]
78 pub fn cursor_show(&mut self) {
79 self.data.extend_from_slice(b"\x1b[?25h");
80 }
81
82 #[inline]
84 pub fn set_fg(&mut self, color: Rgb) {
85 write!(self.data, "\x1b[38;2;{};{};{}m", color.r, color.g, color.b).unwrap();
86 }
87
88 #[inline]
90 pub fn set_bg(&mut self, color: Rgb) {
91 write!(self.data, "\x1b[48;2;{};{};{}m", color.r, color.g, color.b).unwrap();
92 }
93
94 #[inline]
96 pub fn reset_attrs(&mut self) {
97 self.data.extend_from_slice(b"\x1b[0m");
98 }
99
100 #[inline]
102 pub fn clear_screen(&mut self) {
103 self.data.extend_from_slice(b"\x1b[2J");
104 }
105
106 pub fn flush_to<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
112 writer.write_all(&self.data)?;
113 writer.flush()
114 }
115}
116
117impl Default for OutputBuffer {
118 fn default() -> Self {
119 Self::new()
120 }
121}