#[cfg(not(windows))]
use std::os::fd::{AsFd, OwnedFd};
#[cfg(windows)]
use std::os::windows::io::{AsHandle, OwnedHandle};
use std::{
fs::{File, OpenOptions},
io,
path::Path,
process::Stdio,
};
#[cfg(windows)]
type NativeType = OwnedHandle;
#[cfg(not(windows))]
type NativeType = OwnedFd;
pub struct OwnedFileDescriptorOrHandle {
fx: NativeType,
}
impl OwnedFileDescriptorOrHandle {
pub fn new(x: NativeType) -> Self {
Self { fx: x }
}
pub fn open_file(options: &OpenOptions, path: &Path) -> io::Result<Self> {
let f = options.open(path)?;
Self::from(f)
}
#[cfg(windows)]
pub fn from<T: AsHandle>(t: T) -> io::Result<Self> {
Ok(Self {
fx: t.as_handle().try_clone_to_owned()?,
})
}
#[cfg(not(windows))]
pub fn from<T: AsFd>(t: T) -> io::Result<Self> {
Ok(Self {
fx: t.as_fd().try_clone_to_owned()?,
})
}
pub fn into_file(self) -> File {
File::from(self.fx)
}
pub fn into_stdio(self) -> Stdio {
Stdio::from(self.fx)
}
pub fn try_clone(&self) -> io::Result<Self> {
self.fx.try_clone().map(Self::new)
}
pub fn as_raw(&self) -> &NativeType {
&self.fx
}
}
impl From<OwnedFileDescriptorOrHandle> for Stdio {
fn from(value: OwnedFileDescriptorOrHandle) -> Self {
value.into_stdio()
}
}