]> git.proxmox.com Git - rustc.git/blame - vendor/anstyle-wincon/src/stream.rs
New upstream version 1.70.0+dfsg1
[rustc.git] / vendor / anstyle-wincon / src / stream.rs
CommitLineData
353b0b11
FG
1/// Extend `std::io::Write` with wincon styling
2///
3/// Generally, you will want to use [`Console`][crate::Console] instead
4pub trait WinconStream {
5 /// Change the foreground/background
6 ///
7 /// A common pitfall is to forget to flush writes to
8 /// stdout before setting new text attributes.
9 fn set_colors(
10 &mut self,
11 fg: Option<anstyle::AnsiColor>,
12 bg: Option<anstyle::AnsiColor>,
13 ) -> std::io::Result<()>;
14
15 /// Get the current foreground/background colors
16 fn get_colors(
17 &self,
18 ) -> std::io::Result<(Option<anstyle::AnsiColor>, Option<anstyle::AnsiColor>)>;
19}
20
21impl WinconStream for std::io::Stdout {
22 fn set_colors(
23 &mut self,
24 fg: Option<anstyle::AnsiColor>,
25 bg: Option<anstyle::AnsiColor>,
26 ) -> std::io::Result<()> {
27 inner::set_colors(self, fg, bg)
28 }
29
30 fn get_colors(
31 &self,
32 ) -> std::io::Result<(Option<anstyle::AnsiColor>, Option<anstyle::AnsiColor>)> {
33 inner::get_colors(self)
34 }
35}
36
37impl<'s> WinconStream for std::io::StdoutLock<'s> {
38 fn set_colors(
39 &mut self,
40 fg: Option<anstyle::AnsiColor>,
41 bg: Option<anstyle::AnsiColor>,
42 ) -> std::io::Result<()> {
43 inner::set_colors(self, fg, bg)
44 }
45
46 fn get_colors(
47 &self,
48 ) -> std::io::Result<(Option<anstyle::AnsiColor>, Option<anstyle::AnsiColor>)> {
49 inner::get_colors(self)
50 }
51}
52
53impl WinconStream for std::io::Stderr {
54 fn set_colors(
55 &mut self,
56 fg: Option<anstyle::AnsiColor>,
57 bg: Option<anstyle::AnsiColor>,
58 ) -> std::io::Result<()> {
59 inner::set_colors(self, fg, bg)
60 }
61
62 fn get_colors(
63 &self,
64 ) -> std::io::Result<(Option<anstyle::AnsiColor>, Option<anstyle::AnsiColor>)> {
65 inner::get_colors(self)
66 }
67}
68
69impl<'s> WinconStream for std::io::StderrLock<'s> {
70 fn set_colors(
71 &mut self,
72 fg: Option<anstyle::AnsiColor>,
73 bg: Option<anstyle::AnsiColor>,
74 ) -> std::io::Result<()> {
75 inner::set_colors(self, fg, bg)
76 }
77
78 fn get_colors(
79 &self,
80 ) -> std::io::Result<(Option<anstyle::AnsiColor>, Option<anstyle::AnsiColor>)> {
81 inner::get_colors(self)
82 }
83}
84
85#[cfg(windows)]
86mod inner {
87 use std::os::windows::io::{AsHandle, AsRawHandle};
88
89 pub(super) fn set_colors<S: AsHandle>(
90 stream: &mut S,
91 fg: Option<anstyle::AnsiColor>,
92 bg: Option<anstyle::AnsiColor>,
93 ) -> std::io::Result<()> {
94 let handle = stream.as_handle();
95 let handle = handle.as_raw_handle();
96 if let (Some(fg), Some(bg)) = (fg, bg) {
97 let attributes = crate::windows::set_colors(fg, bg);
98 crate::windows::set_console_text_attributes(handle, attributes)
99 } else {
100 Ok(())
101 }
102 }
103
104 pub(super) fn get_colors<S: AsHandle>(
105 stream: &S,
106 ) -> std::io::Result<(Option<anstyle::AnsiColor>, Option<anstyle::AnsiColor>)> {
107 let handle = stream.as_handle();
108 let handle = handle.as_raw_handle();
109 let info = crate::windows::get_screen_buffer_info(handle)?;
110 let (fg, bg) = crate::windows::get_colors(&info);
111 Ok((Some(fg), Some(bg)))
112 }
113}
114
115#[cfg(not(windows))]
116mod inner {
117 pub(super) fn set_colors<S: std::io::Write>(
118 stream: &mut S,
119 fg: Option<anstyle::AnsiColor>,
120 bg: Option<anstyle::AnsiColor>,
121 ) -> std::io::Result<()> {
122 if let Some(fg) = fg {
123 write!(stream, "{}", fg.render_fg())?;
124 }
125 if let Some(bg) = bg {
126 write!(stream, "{}", bg.render_bg())?;
127 }
128 if fg.is_none() && bg.is_none() {
129 write!(stream, "{}", anstyle::Reset.render())?;
130 }
131 Ok(())
132 }
133
134 pub(super) fn get_colors<S>(
135 _stream: &S,
136 ) -> std::io::Result<(Option<anstyle::AnsiColor>, Option<anstyle::AnsiColor>)> {
137 Ok((None, None))
138 }
139}