1use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
2use std::os::fd::{self, AsFd, AsRawFd, BorrowedFd, RawFd};
3
4use crate::{Basic, Type};
5
6#[derive(Debug)]
15pub enum Fd<'f> {
16 Borrowed(BorrowedFd<'f>),
17 Owned(fd::OwnedFd),
18}
19
20impl Fd<'_> {
21 pub fn try_to_owned(&self) -> crate::Result<Fd<'static>> {
23 self.as_fd()
24 .try_clone_to_owned()
25 .map(Fd::Owned)
26 .map_err(Into::into)
27 }
28
29 pub fn try_clone(&self) -> crate::Result<Self> {
31 Ok(match self {
32 Self::Borrowed(fd) => Self::Borrowed(*fd),
33 Self::Owned(fd) => Self::Owned(fd.try_clone()?),
34 })
35 }
36}
37
38impl<'f> From<BorrowedFd<'f>> for Fd<'f> {
39 fn from(fd: BorrowedFd<'f>) -> Self {
40 Self::Borrowed(fd)
41 }
42}
43
44impl From<fd::OwnedFd> for Fd<'_> {
45 fn from(fd: fd::OwnedFd) -> Self {
46 Self::Owned(fd)
47 }
48}
49
50impl From<OwnedFd> for Fd<'_> {
51 fn from(owned: OwnedFd) -> Self {
52 owned.inner
53 }
54}
55
56impl TryFrom<Fd<'_>> for fd::OwnedFd {
57 type Error = crate::Error;
58
59 fn try_from(fd: Fd<'_>) -> crate::Result<Self> {
60 match fd {
61 Fd::Borrowed(fd) => fd.try_clone_to_owned().map_err(Into::into),
62 Fd::Owned(fd) => Ok(fd),
63 }
64 }
65}
66
67impl AsRawFd for Fd<'_> {
68 fn as_raw_fd(&self) -> RawFd {
69 self.as_fd().as_raw_fd()
70 }
71}
72
73impl AsFd for Fd<'_> {
74 fn as_fd(&self) -> BorrowedFd<'_> {
75 match self {
76 Self::Borrowed(fd) => fd.as_fd(),
77 Self::Owned(fd) => fd.as_fd(),
78 }
79 }
80}
81
82impl<'fd, T> From<&'fd T> for Fd<'fd>
83where
84 T: AsFd,
85{
86 fn from(t: &'fd T) -> Self {
87 Self::Borrowed(t.as_fd())
88 }
89}
90
91impl std::fmt::Display for Fd<'_> {
92 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93 self.as_raw_fd().fmt(f)
94 }
95}
96
97macro_rules! fd_impl {
98 ($i:ty) => {
99 impl Basic for $i {
100 const SIGNATURE_CHAR: char = 'h';
101 const SIGNATURE_STR: &'static str = "h";
102 }
103
104 impl Type for $i {
105 const SIGNATURE: &'static crate::Signature = &crate::Signature::Fd;
106 }
107 };
108}
109
110fd_impl!(Fd<'_>);
111
112impl Serialize for Fd<'_> {
113 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
114 where
115 S: Serializer,
116 {
117 serializer.serialize_i32(self.as_raw_fd())
118 }
119}
120
121impl<'de> Deserialize<'de> for Fd<'de> {
122 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
123 where
124 D: Deserializer<'de>,
125 {
126 let raw = i32::deserialize(deserializer)?;
127 let fd = unsafe { BorrowedFd::borrow_raw(raw) };
129
130 Ok(Fd::Borrowed(fd))
131 }
132}
133
134impl PartialEq for Fd<'_> {
135 fn eq(&self, other: &Self) -> bool {
136 self.as_raw_fd().eq(&other.as_raw_fd())
137 }
138}
139impl Eq for Fd<'_> {}
140
141impl PartialOrd for Fd<'_> {
142 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
143 Some(self.cmp(other))
144 }
145}
146
147impl Ord for Fd<'_> {
148 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
149 self.as_raw_fd().cmp(&other.as_raw_fd())
150 }
151}
152
153impl std::hash::Hash for Fd<'_> {
154 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
155 self.as_raw_fd().hash(state)
156 }
157}
158
159#[derive(Debug, PartialEq, Eq, Hash)]
163pub struct OwnedFd {
164 inner: Fd<'static>,
165}
166
167fd_impl!(OwnedFd);
168
169impl Serialize for OwnedFd {
170 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
171 where
172 S: Serializer,
173 {
174 self.inner.serialize(serializer)
175 }
176}
177
178impl<'de> Deserialize<'de> for OwnedFd {
179 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
180 where
181 D: Deserializer<'de>,
182 {
183 let fd = Fd::deserialize(deserializer)?;
184 Ok(OwnedFd {
185 inner: fd
186 .as_fd()
187 .try_clone_to_owned()
188 .map(Fd::Owned)
189 .map_err(D::Error::custom)?,
190 })
191 }
192}
193
194impl AsFd for OwnedFd {
195 fn as_fd(&self) -> BorrowedFd<'_> {
196 self.inner.as_fd()
197 }
198}
199
200impl AsRawFd for OwnedFd {
201 fn as_raw_fd(&self) -> RawFd {
202 self.inner.as_raw_fd()
203 }
204}
205
206impl From<fd::OwnedFd> for OwnedFd {
207 fn from(value: fd::OwnedFd) -> Self {
208 Self {
209 inner: Fd::Owned(value),
210 }
211 }
212}
213
214impl From<OwnedFd> for fd::OwnedFd {
215 fn from(value: OwnedFd) -> fd::OwnedFd {
216 match value.inner {
217 Fd::Owned(fd) => fd,
218 Fd::Borrowed(_) => unreachable!(),
219 }
220 }
221}
222
223impl From<Fd<'static>> for OwnedFd {
224 fn from(value: Fd<'static>) -> Self {
225 Self { inner: value }
226 }
227}
228
229impl std::fmt::Display for OwnedFd {
230 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
231 self.inner.fmt(f)
232 }
233}