Skip to main content

printer/printer/writer/
raw.rs

1use crate::Result;
2use crossterm::{queue, style::*, terminal::*};
3use std::{cell::RefCell, fmt::Display, rc::Rc, sync::OnceLock};
4
5static NO_COLOR: OnceLock<bool> = OnceLock::new();
6fn no_color() -> bool {
7    *NO_COLOR.get_or_init(|| std::env::var("NO_COLOR").is_ok())
8}
9
10#[derive(Debug, Clone)]
11pub struct Raw<W> {
12    pub raw: Rc<RefCell<W>>,
13}
14
15impl<W: std::io::Write> std::io::Write for Raw<W> {
16    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
17        self.raw.borrow_mut().write(buf)
18    }
19    fn flush(&mut self) -> std::io::Result<()> {
20        self.raw.borrow_mut().flush()
21    }
22}
23
24impl<W: std::io::Write> Raw<W> {
25    pub fn scroll_up(&mut self, n: u16) -> Result<()> {
26        queue!(self, ScrollUp(n))?;
27        Ok(())
28    }
29
30    pub fn clear(&mut self, clear_type: ClearType) -> Result<()> {
31        queue!(self, Clear(clear_type))?;
32        Ok(())
33    }
34
35    pub fn _write<D: Display + Clone>(&mut self, value: D) -> Result<()> {
36        queue!(self, Print(value))?;
37        Ok(())
38    }
39
40    pub fn write<D: Display + Clone>(&mut self, value: D) -> Result<()> {
41        self._write(value)
42    }
43
44    pub fn write_with_color<D: Display + Clone>(&mut self, value: D, color: Color) -> Result<()> {
45        self.set_fg(color)?;
46        self.write(value)?;
47        self.reset_color()?;
48        Ok(())
49    }
50
51    pub fn set_title(&mut self, title: &str) -> Result<()> {
52        queue!(self, SetTitle(title))?;
53        Ok(())
54    }
55
56    // color commands
57
58    pub fn reset_color(&mut self) -> Result<()> {
59        if no_color() {
60            return Ok(());
61        }
62        queue!(self, ResetColor)?;
63        Ok(())
64    }
65
66    pub fn set_fg(&mut self, color: Color) -> Result<()> {
67        if no_color() {
68            return Ok(());
69        }
70        queue!(self, SetForegroundColor(color))?;
71        Ok(())
72    }
73
74    pub fn set_bg(&mut self, color: Color) -> Result<()> {
75        if no_color() {
76            return Ok(());
77        }
78        queue!(self, SetBackgroundColor(color))?;
79        Ok(())
80    }
81}