1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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; // TODO: change to isize when fully ported to windows-rs

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)
    }
}