1use std::{cell::Cell, fmt, io};
7
8#[cfg(unix)]
9use std::os::fd::{AsFd, OwnedFd};
10
11#[cfg(windows)]
12use std::os::windows::io::{AsHandle, OwnedHandle};
13
14use serde::{Deserialize, Deserializer, Serialize, Serializer};
15
16#[cfg(unix)]
18pub type DefaultHandle = OwnedFd;
19
20#[cfg(windows)]
22pub type DefaultHandle = std::os::windows::io::OwnedHandle;
23
24pub(crate) trait PutHandle {
26 #[cfg(unix)]
27 fn put_handle(&mut self, handle: &dyn ErasedHandle) -> io::Result<u32>;
28 #[cfg(windows)]
29 fn put_handle(&mut self, handle: &dyn ErasedHandle) -> io::Result<usize>;
30 fn put_opaque(&mut self, opaque: &crate::session::Inner) -> io::Result<(u8, u64)>;
33}
34
35pub(crate) trait ErasedHandle {
36 #[cfg(unix)]
37 fn steal_handle(&self) -> Option<OwnedFd>;
38 #[cfg(windows)]
39 fn steal_handle(&self) -> Option<OwnedHandle>;
40}
41
42pub(crate) trait TakeHandle {
44 #[cfg(unix)]
45 fn take_handle(&mut self, index: u32) -> io::Result<OwnedFd>;
46 #[cfg(windows)]
47 fn take_handle(&mut self, value: usize) -> io::Result<OwnedHandle>;
48
49 fn finish(&mut self) -> io::Result<()> {
50 Ok(())
51 }
52 fn take_gift(&mut self, owner: u8, id: u64) -> io::Result<crate::session::Inner>;
55
56 fn take_cite(
63 &mut self,
64 owner: u8,
65 id: u64,
66 marker: std::any::TypeId,
67 ) -> io::Result<crate::session::Inner>;
68}
69
70pub struct OsHandle<T = DefaultHandle>(Cell<Option<T>>);
76
77impl<T> fmt::Debug for OsHandle<T> {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 f.write_str("OsHandle(..)")
80 }
81}
82
83impl<T> OsHandle<T> {
84 pub fn new(value: T) -> Self {
86 Self(Cell::new(Some(value)))
87 }
88
89 pub fn into_inner(self) -> T {
95 self.0
96 .into_inner()
97 .expect("operating-system handle was already consumed")
98 }
99}
100
101impl<T> From<T> for OsHandle<T> {
102 fn from(value: T) -> Self {
103 Self::new(value)
104 }
105}
106
107#[cfg(unix)]
108impl<T: AsFd + Into<OwnedFd>> ErasedHandle for OsHandle<T> {
109 fn steal_handle(&self) -> Option<OwnedFd> {
110 self.0.take().map(Into::into)
111 }
112}
113
114#[cfg(unix)]
115impl<T: AsFd + Into<OwnedFd>> Serialize for OsHandle<T> {
116 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
117 crate::serde::serialize_handle(self, serializer)
118 }
119}
120
121#[cfg(unix)]
122impl<'de, T: From<OwnedFd>> Deserialize<'de> for OsHandle<T> {
123 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
124 crate::serde::deserialize_handle(deserializer).map(|handle| OsHandle::new(T::from(handle)))
125 }
126}
127
128#[cfg(windows)]
129impl<T: AsHandle + Into<OwnedHandle>> ErasedHandle for OsHandle<T> {
130 fn steal_handle(&self) -> Option<OwnedHandle> {
131 self.0.take().map(Into::into)
132 }
133}
134
135#[cfg(windows)]
136impl<T: AsHandle + Into<OwnedHandle>> Serialize for OsHandle<T> {
137 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
138 crate::serde::serialize_handle(self, serializer)
139 }
140}
141
142#[cfg(windows)]
143impl<'de, T: From<OwnedHandle>> Deserialize<'de> for OsHandle<T> {
144 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
145 crate::serde::deserialize_handle(deserializer).map(|handle| OsHandle::new(T::from(handle)))
146 }
147}