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