Skip to main content

pyo3/conversions/
serde.rs

1#![cfg(feature = "serde")]
2
3//! Enables (de)serialization of [`Py`]`<T>` objects via [serde](https://docs.rs/serde).
4//!
5//! # Setup
6//!
7//! To use this feature, add this to your **`Cargo.toml`**:
8//!
9//! ```toml
10//! [dependencies]
11#![doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"),  "\", features = [\"serde\"] }")]
12//! serde = "1.0"
13//! ```
14
15use crate::platform::prelude::*;
16use crate::{Py, PyAny, PyClass, Python};
17use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer};
18
19impl<T> Serialize for Py<T>
20where
21    T: Serialize + PyClass,
22{
23    fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
24    where
25        S: Serializer,
26    {
27        Python::attach(|py| {
28            self.try_borrow(py)
29                .map_err(|e| ser::Error::custom(e.to_string()))?
30                .serialize(serializer)
31        })
32    }
33}
34
35impl<'de, T> Deserialize<'de> for Py<T>
36where
37    T: PyClass<BaseType = PyAny> + Deserialize<'de>,
38{
39    fn deserialize<D>(deserializer: D) -> Result<Py<T>, D::Error>
40    where
41        D: Deserializer<'de>,
42    {
43        let deserialized = T::deserialize(deserializer)?;
44
45        Python::attach(|py| Py::new(py, deserialized).map_err(|e| de::Error::custom(e.to_string())))
46    }
47}