1use std::{
2 fs, io,
3 os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd},
4};
5
6/// If the `calloop` cargo feature is enabled, this can be used
7/// as an `EventSource` in a calloop event loop.
8#[must_use]
9#[derive(Debug)]
10pub struct WritePipe {
11 #[cfg(feature = "calloop")]
12 file: calloop::generic::Generic<fs::File>,
13 #[cfg(not(feature = "calloop"))]
14 file: fs::File,
15}
16
17#[cfg(feature = "calloop")]
18impl io::Write for WritePipe {
19 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
20 unsafe { self.file.get_mut().write(buf) }
21 }
22
23 fn flush(&mut self) -> io::Result<()> {
24 unsafe { self.file.get_mut().flush() }
25 }
26}
27
28#[cfg(not(feature = "calloop"))]
29impl io::Write for WritePipe {
30 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
31 self.file.write(buf)
32 }
33
34 fn flush(&mut self) -> io::Result<()> {
35 self.file.flush()
36 }
37}
38
39#[cfg(feature = "calloop")]
40impl FromRawFd for WritePipe {
41 unsafe fn from_raw_fd(fd: RawFd) -> WritePipe {
42 WritePipe {
43 file: calloop::generic::Generic::new(
44 file:unsafe { FromRawFd::from_raw_fd(fd) },
45 interest:calloop::Interest::WRITE,
46 calloop::Mode::Level,
47 ),
48 }
49 }
50}
51
52#[cfg(feature = "calloop")]
53impl From<OwnedFd> for WritePipe {
54 fn from(owned: OwnedFd) -> Self {
55 WritePipe {
56 file: calloop::generic::Generic::new(
57 file:owned.into(),
58 interest:calloop::Interest::WRITE,
59 calloop::Mode::Level,
60 ),
61 }
62 }
63}
64
65#[cfg(not(feature = "calloop"))]
66impl FromRawFd for WritePipe {
67 unsafe fn from_raw_fd(fd: RawFd) -> WritePipe {
68 WritePipe { file: unsafe { FromRawFd::from_raw_fd(fd) } }
69 }
70}
71
72#[cfg(not(feature = "calloop"))]
73impl From<OwnedFd> for WritePipe {
74 fn from(owned: OwnedFd) -> Self {
75 WritePipe { file: owned.into() }
76 }
77}
78
79#[cfg(feature = "calloop")]
80impl AsRawFd for WritePipe {
81 fn as_raw_fd(&self) -> RawFd {
82 self.file.get_ref().as_raw_fd()
83 }
84}
85
86#[cfg(feature = "calloop")]
87impl AsFd for WritePipe {
88 fn as_fd(&self) -> BorrowedFd {
89 self.file.get_ref().as_fd()
90 }
91}
92
93#[cfg(not(feature = "calloop"))]
94impl AsRawFd for WritePipe {
95 fn as_raw_fd(&self) -> RawFd {
96 self.file.as_raw_fd()
97 }
98}
99#[cfg(not(feature = "calloop"))]
100
101impl AsFd for WritePipe {
102 fn as_fd(&self) -> BorrowedFd<'_> {
103 self.file.as_fd()
104 }
105}
106
107#[cfg(feature = "calloop")]
108impl IntoRawFd for WritePipe {
109 fn into_raw_fd(self) -> RawFd {
110 self.file.unwrap().into_raw_fd()
111 }
112}
113
114#[cfg(feature = "calloop")]
115impl From<WritePipe> for OwnedFd {
116 fn from(write_pipe: WritePipe) -> Self {
117 write_pipe.file.unwrap().into()
118 }
119}
120
121#[cfg(not(feature = "calloop"))]
122impl IntoRawFd for WritePipe {
123 fn into_raw_fd(self) -> RawFd {
124 self.file.into_raw_fd()
125 }
126}
127
128#[cfg(not(feature = "calloop"))]
129impl From<WritePipe> for OwnedFd {
130 fn from(write_pipe: WritePipe) -> Self {
131 write_pipe.file.into()
132 }
133}
134
135#[cfg(feature = "calloop")]
136impl calloop::EventSource for WritePipe {
137 type Event = ();
138 type Error = std::io::Error;
139 type Metadata = calloop::generic::NoIoDrop<fs::File>;
140 type Ret = calloop::PostAction;
141
142 fn process_events<F>(
143 &mut self,
144 readiness: calloop::Readiness,
145 token: calloop::Token,
146 mut callback: F,
147 ) -> std::io::Result<calloop::PostAction>
148 where
149 F: FnMut((), &mut calloop::generic::NoIoDrop<fs::File>) -> Self::Ret,
150 {
151 self.file.process_events(readiness, token, |_, file| Ok(callback((), file)))
152 }
153
154 fn register(
155 &mut self,
156 poll: &mut calloop::Poll,
157 token_factory: &mut calloop::TokenFactory,
158 ) -> calloop::Result<()> {
159 self.file.register(poll, token_factory)
160 }
161
162 fn reregister(
163 &mut self,
164 poll: &mut calloop::Poll,
165 token_factory: &mut calloop::TokenFactory,
166 ) -> calloop::Result<()> {
167 self.file.reregister(poll, token_factory)
168 }
169
170 fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> {
171 self.file.unregister(poll)
172 }
173}
174