monarch_types/
lib.rs

1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree.
7 */
8
9#![feature(assert_matches)]
10
11mod pyobject;
12mod python;
13mod pytree;
14
15use std::error::Error;
16
17use pyo3::PyErr;
18use pyo3::exceptions::PyValueError;
19pub use pyobject::PickledPyObject;
20pub use python::SerializablePyErr;
21pub use python::TryIntoPyObjectUnsafe;
22pub use pytree::PyTree;
23
24/// Macro to generate a Python object lookup function with caching
25///
26/// # Arguments
27/// * `$fn_name` - Name of the Rust function to generate
28/// * `$python_path` - Path to the Python object as a string (e.g., "module.submodule.function")
29#[macro_export]
30macro_rules! py_global {
31    ($fn_name:ident, $python_module:literal, $python_class:literal) => {
32        fn $fn_name<'py>(py: ::pyo3::Python<'py>) -> ::pyo3::Bound<'py, ::pyo3::PyAny> {
33            static CACHE: ::pyo3::sync::GILOnceCell<::pyo3::PyObject> =
34                ::pyo3::sync::GILOnceCell::new();
35            CACHE
36                .import(py, $python_module, $python_class)
37                .unwrap()
38                .clone()
39        }
40    };
41}
42
43pub trait MapPyErr<T> {
44    fn map_pyerr(self) -> Result<T, PyErr>;
45}
46impl<T, E> MapPyErr<T> for Result<T, E>
47where
48    E: ToString,
49{
50    fn map_pyerr(self) -> Result<T, PyErr> {
51        self.map_err(|err| PyErr::new::<PyValueError, _>(err.to_string()))
52    }
53}