maybe_fut/api/io/
stderr.rs1#[derive(Debug, Write, Unwrap)]
3#[io(feature("tokio"))]
4#[unwrap_types(std(std::io::Stderr), tokio(tokio::io::Stderr), tokio_gated("tokio"))]
5pub struct Stderr(StderrInner);
6
7#[derive(Debug)]
8enum StderrInner {
9 Std(std::io::Stderr),
10 #[cfg(tokio)]
11 Tokio(tokio::io::Stderr),
12}
13
14impl From<std::io::Stderr> for Stderr {
15 fn from(stderr: std::io::Stderr) -> Self {
16 Self(StderrInner::Std(stderr))
17 }
18}
19
20#[cfg(tokio)]
21#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
22impl From<tokio::io::Stderr> for Stderr {
23 fn from(stderr: tokio::io::Stderr) -> Self {
24 Self(StderrInner::Tokio(stderr))
25 }
26}
27
28pub fn stderr() -> Stderr {
30 #[cfg(tokio)]
31 {
32 if crate::is_async_context() {
33 tokio::io::stderr().into()
34 } else {
35 std::io::stderr().into()
36 }
37 }
38 #[cfg(not(tokio))]
39 {
40 std::io::stderr().into()
41 }
42}
43
44#[cfg(unix)]
45impl std::os::fd::AsFd for Stderr {
46 fn as_fd(&self) -> std::os::fd::BorrowedFd<'_> {
47 match &self.0 {
48 StderrInner::Std(file) => file.as_fd(),
49 #[cfg(tokio)]
50 StderrInner::Tokio(file) => file.as_fd(),
51 }
52 }
53}
54
55#[cfg(windows)]
56impl std::os::windows::io::AsHandle for Stderr {
57 fn as_handle(&self) -> std::os::windows::io::BorrowedHandle<'_> {
58 match &self.0 {
59 StderrInner::Std(file) => file.as_handle(),
60 #[cfg(tokio)]
61 StderrInner::Tokio(file) => file.as_handle(),
62 }
63 }
64}
65
66#[cfg(unix)]
67impl std::os::fd::AsRawFd for Stderr {
68 fn as_raw_fd(&self) -> std::os::fd::RawFd {
69 match &self.0 {
70 StderrInner::Std(file) => file.as_raw_fd(),
71 #[cfg(tokio)]
72 StderrInner::Tokio(file) => file.as_raw_fd(),
73 }
74 }
75}
76
77#[cfg(windows)]
78impl std::os::windows::io::AsRawHandle for Stderr {
79 fn as_raw_handle(&self) -> std::os::windows::io::RawHandle {
80 match &self.0 {
81 StderrInner::Std(file) => file.as_raw_handle(),
82 #[cfg(tokio)]
83 StderrInner::Tokio(file) => file.as_raw_handle(),
84 }
85 }
86}
87
88#[cfg(test)]
89mod test {
90
91 use super::*;
92
93 #[test]
94 fn test_should_stderr_sync() {
95 let stderr = stderr();
96 assert!(matches!(stderr.0, StderrInner::Std(_)));
97 }
98
99 #[cfg(tokio)]
100 #[tokio::test]
101 async fn test_should_stderr_async() {
102 let stderr = stderr();
103 assert!(matches!(stderr.0, StderrInner::Tokio(_)));
104 }
105}