pyo3/conversions/std/
option.rs1use crate::{
2 ffi, types::any::PyAnyMethods, AsPyPointer, Bound, FromPyObject, IntoPy, PyAny, PyObject,
3 PyResult, Python, ToPyObject,
4};
5
6impl<T> ToPyObject for Option<T>
9where
10 T: ToPyObject,
11{
12 fn to_object(&self, py: Python<'_>) -> PyObject {
13 self.as_ref()
14 .map_or_else(|| py.None(), |val| val.to_object(py))
15 }
16}
17
18impl<T> IntoPy<PyObject> for Option<T>
19where
20 T: IntoPy<PyObject>,
21{
22 fn into_py(self, py: Python<'_>) -> PyObject {
23 self.map_or_else(|| py.None(), |val| val.into_py(py))
24 }
25}
26
27impl<'py, T> FromPyObject<'py> for Option<T>
28where
29 T: FromPyObject<'py>,
30{
31 fn extract_bound(obj: &Bound<'py, PyAny>) -> PyResult<Self> {
32 if obj.is_none() {
33 Ok(None)
34 } else {
35 obj.extract().map(Some)
36 }
37 }
38}
39
40unsafe impl<T> AsPyPointer for Option<T>
42where
43 T: AsPyPointer,
44{
45 #[inline]
46 fn as_ptr(&self) -> *mut ffi::PyObject {
47 self.as_ref()
48 .map_or_else(std::ptr::null_mut, |t| t.as_ptr())
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use crate::{PyObject, Python};
55
56 #[test]
57 fn test_option_as_ptr() {
58 Python::with_gil(|py| {
59 use crate::AsPyPointer;
60 let mut option: Option<PyObject> = None;
61 assert_eq!(option.as_ptr(), std::ptr::null_mut());
62
63 let none = py.None();
64 option = Some(none.clone_ref(py));
65
66 let ref_cnt = none.get_refcnt(py);
67 assert_eq!(option.as_ptr(), none.as_ptr());
68
69 assert_eq!(none.get_refcnt(py), ref_cnt);
71 });
72 }
73}