Skip to main content

pyo3/conversions/std/
option.rs

1#[cfg(feature = "experimental-inspect")]
2use crate::inspect::{type_hint_union, PyStaticExpr};
3#[cfg(feature = "experimental-inspect")]
4use crate::type_object::PyTypeInfo;
5#[cfg(feature = "experimental-inspect")]
6use crate::types::PyNone;
7use crate::{
8    conversion::IntoPyObject, types::any::PyAnyMethods, BoundObject, FromPyObject, PyAny, Python,
9};
10use crate::{Borrowed, Bound};
11
12impl<'py, T> IntoPyObject<'py> for Option<T>
13where
14    T: IntoPyObject<'py>,
15{
16    type Target = PyAny;
17    type Output = Bound<'py, Self::Target>;
18    type Error = T::Error;
19    #[cfg(feature = "experimental-inspect")]
20    const OUTPUT_TYPE: PyStaticExpr = type_hint_union!(&T::OUTPUT_TYPE, PyNone::TYPE_HINT);
21
22    fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
23        self.map_or_else(
24            || Ok(py.None().into_bound(py)),
25            |val| {
26                val.into_pyobject(py)
27                    .map(BoundObject::into_any)
28                    .map(BoundObject::into_bound)
29            },
30        )
31    }
32}
33
34impl<'a, 'py, T> IntoPyObject<'py> for &'a Option<T>
35where
36    &'a T: IntoPyObject<'py>,
37{
38    type Target = PyAny;
39    type Output = Bound<'py, Self::Target>;
40    type Error = <&'a T as IntoPyObject<'py>>::Error;
41    #[cfg(feature = "experimental-inspect")]
42    const OUTPUT_TYPE: PyStaticExpr = <Option<&T>>::OUTPUT_TYPE;
43
44    #[inline]
45    fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
46        self.as_ref().into_pyobject(py)
47    }
48}
49
50impl<'a, 'py, T> FromPyObject<'a, 'py> for Option<T>
51where
52    T: FromPyObject<'a, 'py>,
53{
54    type Error = T::Error;
55    #[cfg(feature = "experimental-inspect")]
56    const INPUT_TYPE: PyStaticExpr = type_hint_union!(T::INPUT_TYPE, PyNone::TYPE_HINT);
57
58    fn extract(obj: Borrowed<'a, 'py, PyAny>) -> Result<Self, Self::Error> {
59        if obj.is_none() {
60            Ok(None)
61        } else {
62            obj.extract().map(Some)
63        }
64    }
65}