1 | use crate::{IntoPy, Py, PyAny, PyErr, PyObject, PyResult, Python}; |
2 | |
3 | /// Used to wrap values in `Option<T>` for default arguments. |
4 | pub trait SomeWrap<T> { |
5 | fn wrap(self) -> T; |
6 | } |
7 | |
8 | impl<T> SomeWrap<Option<T>> for T { |
9 | fn wrap(self) -> Option<T> { |
10 | Some(self) |
11 | } |
12 | } |
13 | |
14 | impl<T> SomeWrap<Option<T>> for Option<T> { |
15 | fn wrap(self) -> Self { |
16 | self |
17 | } |
18 | } |
19 | |
20 | /// Used to wrap the result of `#[pyfunction]` and `#[pymethods]`. |
21 | pub trait OkWrap<T> { |
22 | type Error; |
23 | fn wrap(self, py: Python<'_>) -> Result<Py<PyAny>, Self::Error>; |
24 | } |
25 | |
26 | // The T: IntoPy<PyObject> bound here is necessary to prevent the |
27 | // implementation for Result<T, E> from conflicting |
28 | impl<T> OkWrap<T> for T |
29 | where |
30 | T: IntoPy<PyObject>, |
31 | { |
32 | type Error = PyErr; |
33 | fn wrap(self, py: Python<'_>) -> PyResult<Py<PyAny>> { |
34 | Ok(self.into_py(py)) |
35 | } |
36 | } |
37 | |
38 | impl<T, E> OkWrap<T> for Result<T, E> |
39 | where |
40 | T: IntoPy<PyObject>, |
41 | { |
42 | type Error = E; |
43 | fn wrap(self, py: Python<'_>) -> Result<Py<PyAny>, Self::Error> { |
44 | self.map(|o: T| o.into_py(py)) |
45 | } |
46 | } |
47 | |
48 | #[cfg (test)] |
49 | mod tests { |
50 | use super::*; |
51 | |
52 | #[test ] |
53 | fn wrap_option() { |
54 | let a: Option<u8> = SomeWrap::wrap(42); |
55 | assert_eq!(a, Some(42)); |
56 | |
57 | let b: Option<u8> = SomeWrap::wrap(None); |
58 | assert_eq!(b, None); |
59 | } |
60 | } |
61 | |