rust/hg-pyo3/src/convert_cpython.rs
changeset 52529 bd65cb043aa5
parent 52528 1dd673c1ab3b
child 52530 736551565871
equal deleted inserted replaced
52528:1dd673c1ab3b 52529:bd65cb043aa5
   210             .try_borrow(py)
   210             .try_borrow(py)
   211             .map_err(|e| from_cpython_pyerr(py, e))?
   211             .map_err(|e| from_cpython_pyerr(py, e))?
   212     };
   212     };
   213     Ok(py_shared.inner)
   213     Ok(py_shared.inner)
   214 }
   214 }
       
   215 
       
   216 /// Error propagation for an [`UnsafePyLeaked`] wrapping a [`Result`]
       
   217 ///
       
   218 /// TODO (will consider when implementing UnsafePyLeaked in PyO3):
       
   219 /// It would be nice for UnsafePyLeaked to provide this directly as a variant
       
   220 /// of the `map` method with a signature such as:
       
   221 ///
       
   222 /// ```
       
   223 ///   unsafe fn map_or_err(&self,
       
   224 ///                        py: Python,
       
   225 ///                        f: impl FnOnce(T) -> Result(U, E),
       
   226 ///                        convert_err: impl FnOnce(E) -> PyErr)
       
   227 /// ```
       
   228 ///
       
   229 /// This would spare users of the `cpython` crate the additional `unsafe` deref
       
   230 /// to inspect the error and return it outside `UnsafePyLeaked`, and the
       
   231 /// subsequent unwrapping that this function performs.
       
   232 #[allow(dead_code)]
       
   233 pub(crate) fn py_leaked_or_map_err<T, E: std::fmt::Debug + Copy>(
       
   234     py: cpython::Python,
       
   235     leaked: cpython::UnsafePyLeaked<Result<T, E>>,
       
   236     convert_err: impl FnOnce(E) -> PyErr,
       
   237 ) -> PyResult<cpython::UnsafePyLeaked<T>> {
       
   238     // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
       
   239     if let Err(e) = *unsafe {
       
   240         leaked
       
   241             .try_borrow(py)
       
   242             .map_err(|e| from_cpython_pyerr(py, e))?
       
   243     } {
       
   244         return Err(convert_err(e));
       
   245     }
       
   246     // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
       
   247     Ok(unsafe {
       
   248         leaked.map(py, |res| {
       
   249             res.expect("Error case should have already be treated")
       
   250         })
       
   251     })
       
   252 }