Show More
@@ -212,3 +212,41 pub(crate) unsafe fn proxy_index_extract | |||||
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 | } |
General Comments 0
You need to be logged in to leave comments.
Login now