1use crate::{IntoPy, Py, PyAny, PyErr, PyObject, PyResult, Python};
2
3/// Used to wrap values in `Option<T>` for default arguments.
4pub trait SomeWrap<T> {
5 fn wrap(self) -> T;
6}
7
8impl<T> SomeWrap<Option<T>> for T {
9 fn wrap(self) -> Option<T> {
10 Some(self)
11 }
12}
13
14impl<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]`.
21pub 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
28impl<T> OkWrap<T> for T
29where
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
38impl<T, E> OkWrap<T> for Result<T, E>
39where
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)]
49mod 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