1use std::io;
2
3use compio_buf::{BufResult, IoBuf, IoBufMut, IoVectoredBuf, IoVectoredBufMut};
4use compio_driver::{AsFd, AsRawFd, BorrowedFd, BufferRef, RawFd};
5use compio_io::{AsyncRead, AsyncReadManaged, AsyncReadMulti, AsyncWrite};
6use compio_runtime::fd::AsyncFd;
7use futures_util::Stream;
8use rustix::stdio::{raw_stderr, raw_stdin, raw_stdout};
9
10#[cfg(doc)]
11use super::{stderr, stdin, stdout};
12
13#[derive(Debug)]
14struct StaticFd(RawFd);
15
16impl StaticFd {
17 const STDERR: Self = Self(raw_stderr());
18 const STDIN: Self = Self(raw_stdin());
19 const STDOUT: Self = Self(raw_stdout());
20}
21
22impl AsFd for StaticFd {
23 fn as_fd(&self) -> BorrowedFd<'_> {
24 unsafe { BorrowedFd::borrow_raw(self.0) }
25 }
26}
27
28impl AsRawFd for StaticFd {
29 fn as_raw_fd(&self) -> RawFd {
30 self.0 as _
31 }
32}
33
34#[derive(Debug, Clone)]
38pub struct Stdin(AsyncFd<StaticFd>);
39
40impl Stdin {
41 pub(crate) fn new() -> Self {
42 Self(unsafe { AsyncFd::new_unchecked(StaticFd::STDIN) })
44 }
45}
46
47impl AsyncRead for Stdin {
48 async fn read<B: IoBufMut>(&mut self, buf: B) -> BufResult<usize, B> {
49 (&*self).read(buf).await
50 }
51
52 async fn read_vectored<V: IoVectoredBufMut>(&mut self, buf: V) -> BufResult<usize, V> {
53 (&*self).read_vectored(buf).await
54 }
55}
56
57impl AsyncRead for &Stdin {
58 async fn read<B: IoBufMut>(&mut self, buf: B) -> BufResult<usize, B> {
59 (&self.0).read(buf).await
60 }
61
62 async fn read_vectored<V: IoVectoredBufMut>(&mut self, buf: V) -> BufResult<usize, V> {
63 (&self.0).read_vectored(buf).await
64 }
65}
66
67impl AsyncReadManaged for Stdin {
68 type Buffer = BufferRef;
69
70 async fn read_managed(&mut self, len: usize) -> io::Result<Option<Self::Buffer>> {
71 (&*self).read_managed(len).await
72 }
73}
74
75impl AsyncReadManaged for &Stdin {
76 type Buffer = BufferRef;
77
78 async fn read_managed(&mut self, len: usize) -> io::Result<Option<Self::Buffer>> {
79 (&self.0).read_managed(len).await
80 }
81}
82
83impl AsyncReadMulti for Stdin {
84 fn read_multi(&mut self, len: usize) -> impl Stream<Item = io::Result<Self::Buffer>> {
85 self.0.read_multi(len)
86 }
87}
88
89impl AsyncReadMulti for &Stdin {
90 fn read_multi(&mut self, len: usize) -> impl Stream<Item = io::Result<Self::Buffer>> {
91 self.0.read_multi_shared(len)
92 }
93}
94
95impl AsRawFd for Stdin {
96 fn as_raw_fd(&self) -> RawFd {
97 self.0.as_raw_fd()
98 }
99}
100
101#[derive(Debug, Clone)]
105pub struct Stdout(AsyncFd<StaticFd>);
106
107impl Stdout {
108 pub(crate) fn new() -> Self {
109 Self(unsafe { AsyncFd::new_unchecked(StaticFd::STDOUT) })
111 }
112}
113
114impl AsyncWrite for Stdout {
115 async fn write<T: IoBuf>(&mut self, buf: T) -> BufResult<usize, T> {
116 self.0.write(buf).await
117 }
118
119 async fn write_vectored<T: IoVectoredBuf>(&mut self, buf: T) -> BufResult<usize, T> {
120 self.0.write_vectored(buf).await
121 }
122
123 async fn flush(&mut self) -> io::Result<()> {
124 self.0.flush().await
125 }
126
127 async fn shutdown(&mut self) -> io::Result<()> {
128 self.0.shutdown().await
129 }
130}
131
132impl AsRawFd for Stdout {
133 fn as_raw_fd(&self) -> RawFd {
134 self.0.as_raw_fd()
135 }
136}
137
138#[derive(Debug, Clone)]
142pub struct Stderr(AsyncFd<StaticFd>);
143
144impl Stderr {
145 pub(crate) fn new() -> Self {
146 Self(unsafe { AsyncFd::new_unchecked(StaticFd::STDERR) })
148 }
149}
150
151impl AsyncWrite for Stderr {
152 async fn write<T: IoBuf>(&mut self, buf: T) -> BufResult<usize, T> {
153 self.0.write(buf).await
154 }
155
156 async fn write_vectored<T: IoVectoredBuf>(&mut self, buf: T) -> BufResult<usize, T> {
157 self.0.write_vectored(buf).await
158 }
159
160 async fn flush(&mut self) -> io::Result<()> {
161 self.0.flush().await
162 }
163
164 async fn shutdown(&mut self) -> io::Result<()> {
165 self.0.shutdown().await
166 }
167}
168
169impl AsRawFd for Stderr {
170 fn as_raw_fd(&self) -> RawFd {
171 self.0.as_raw_fd()
172 }
173}