pyo3/conversions/std/
option.rs1#[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}