1#![cfg_attr(windows, allow(private_interfaces))]
2
3use std::io::BufWriter;
4use std::io::LineWriter;
5#[cfg(any(doc, not(feature = "specialization")))]
6use std::io::Stderr;
7#[cfg(any(doc, not(feature = "specialization")))]
8use std::io::StderrLock;
9#[cfg(any(doc, not(feature = "specialization")))]
10use std::io::Stdout;
11#[cfg(any(doc, not(feature = "specialization")))]
12use std::io::StdoutLock;
13use std::io::Write;
14#[cfg(all(feature = "specialization", windows))]
15use std::os::windows::io::AsHandle;
16
17#[cfg(windows)]
18use super::console::Console;
19
20#[cfg(windows)]
21pub(super) trait ToConsole {
22 fn to_console(&self) -> Option<Console<'_>>;
23}
24
25#[cfg(all(feature = "specialization", windows))]
26impl<T> ToConsole for T
27where
28 T: ?Sized,
29{
30 default fn to_console(&self) -> Option<Console<'_>> {
31 None
32 }
33}
34
35#[cfg(all(feature = "specialization", windows))]
36impl<T> ToConsole for T
37where
38 T: AsHandle + ?Sized + Write,
39{
40 fn to_console(&self) -> Option<Console<'_>> {
41 Console::from_handle(self)
42 }
43}
44
45pub trait WriteLossy {
53 #[cfg(windows)]
54 #[doc(hidden)]
55 fn __to_console(&self) -> Option<Console<'_>>;
56}
57
58#[cfg(feature = "specialization")]
59#[cfg_attr(print_bytes_docs_rs, doc(cfg(feature = "specialization")))]
60impl<T> WriteLossy for T
61where
62 T: ?Sized,
63{
64 #[cfg(windows)]
65 default fn __to_console(&self) -> Option<Console<'_>> {
66 self.to_console()
67 }
68}
69
70macro_rules! r#impl {
71 ( $generic:ident , $type:ty ) => {
72 impl<$generic> WriteLossy for $type
73 where
74 $generic: ?Sized + WriteLossy,
75 {
76 #[cfg(windows)]
77 fn __to_console(&self) -> Option<Console<'_>> {
78 (**self).__to_console()
79 }
80 }
81 };
82}
83r#impl!(T, &mut T);
84r#impl!(T, Box<T>);
85
86macro_rules! r#impl {
87 ( $generic:ident , $type:ty ) => {
88 impl<$generic> WriteLossy for $type
89 where
90 $generic: Write + WriteLossy,
91 {
92 #[cfg(windows)]
93 fn __to_console(&self) -> Option<Console<'_>> {
94 self.get_ref().__to_console()
95 }
96 }
97 };
98}
99r#impl!(T, BufWriter<T>);
100r#impl!(T, LineWriter<T>);
101
102macro_rules! impl_to_console {
103 ( $(#[ $attr:meta ])* $type:ty , $to_console_fn:expr , ) => {
104 #[cfg(any(doc, not(feature = "specialization")))]
105 impl $crate::WriteLossy for $type {
106 #[cfg(windows)]
107 fn __to_console(&self) -> Option<Console<'_>> {
108 $crate::writer::ToConsole::to_console(self)
109 }
110 }
111
112 #[cfg(windows)]
113 $(#[$attr])*
114 impl $crate::writer::ToConsole for $type {
115 fn to_console<'a>(&'a self) -> Option<Console<'a>> {
116 let to_console_fn: fn(&'a Self) -> _ = $to_console_fn;
117 to_console_fn(self)
118 }
119 }
120 };
121}
122
123macro_rules! r#impl {
124 ( $($type:ty),+ ) => {
125 $(
126 impl_to_console! {
127 #[cfg(not(feature = "specialization"))]
128 $type, Console::from_handle,
129 }
130 )+
131 };
132}
133r#impl!(Stderr, StderrLock<'_>, Stdout, StdoutLock<'_>);
134
135impl_to_console! {
136 #[cfg(not(feature = "specialization"))]
137 Vec<u8>, |_| None,
138}