use crate::{
convert::{ToPyObject, ToPyResult},
stdlib::os::errno_err,
PyObjectRef, PyResult, TryFromObject, VirtualMachine,
};
use windows::Win32::Foundation::HANDLE;
use windows_sys::Win32::Foundation::{BOOL, HANDLE as RAW_HANDLE, INVALID_HANDLE_VALUE};
pub(crate) trait WindowsSysResultValue {
type Ok: ToPyObject;
fn is_err(&self) -> bool;
fn into_ok(self) -> Self::Ok;
}
impl WindowsSysResultValue for RAW_HANDLE {
type Ok = HANDLE;
fn is_err(&self) -> bool {
*self == INVALID_HANDLE_VALUE
}
fn into_ok(self) -> Self::Ok {
HANDLE(self)
}
}
impl WindowsSysResultValue for BOOL {
type Ok = ();
fn is_err(&self) -> bool {
*self == 0
}
fn into_ok(self) -> Self::Ok {}
}
pub(crate) struct WindowsSysResult<T>(pub T);
impl<T: WindowsSysResultValue> WindowsSysResult<T> {
pub fn is_err(&self) -> bool {
self.0.is_err()
}
pub fn into_pyresult(self, vm: &VirtualMachine) -> PyResult<T::Ok> {
if self.is_err() {
Err(errno_err(vm))
} else {
Ok(self.0.into_ok())
}
}
}
impl<T: WindowsSysResultValue> ToPyResult for WindowsSysResult<T> {
fn to_pyresult(self, vm: &VirtualMachine) -> PyResult {
let ok = self.into_pyresult(vm)?;
Ok(ok.to_pyobject(vm))
}
}
type HandleInt = usize; impl TryFromObject for HANDLE {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
let handle = HandleInt::try_from_object(vm, obj)?;
Ok(HANDLE(handle as isize))
}
}
impl ToPyObject for HANDLE {
fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef {
(self.0 as HandleInt).to_pyobject(vm)
}
}