pyany_serde/pyany_serde_impl/
python_serde_serde.rs

1use pyo3::ffi::{PyBUF_READ, PyBUF_WRITE, PyMemoryView_FromMemory};
2use pyo3::types::PyBytes;
3use pyo3::{intern, prelude::*};
4use std::os::raw::c_char;
5
6use crate::PyAnySerde;
7
8#[derive(Clone)]
9pub struct PythonSerdeSerde {
10    pub python_serde: PyObject,
11}
12
13impl PyAnySerde for PythonSerdeSerde {
14    fn append<'py>(
15        &mut self,
16        buf: &mut [u8],
17        offset: usize,
18        obj: &Bound<'py, PyAny>,
19    ) -> PyResult<usize> {
20        let py = obj.py();
21        let memory_view = unsafe {
22            Bound::<'py, PyAny>::from_owned_ptr(
23                py,
24                PyMemoryView_FromMemory(
25                    buf.as_mut_ptr() as *mut c_char,
26                    buf.len().try_into().unwrap(),
27                    PyBUF_WRITE,
28                ),
29            )
30        };
31
32        self.python_serde
33            .bind(obj.py())
34            .call_method1(intern!(py, "append"), (memory_view, offset, obj))?
35            .extract()
36    }
37
38    fn append_vec<'py>(
39        &mut self,
40        v: &mut Vec<u8>,
41        start_addr: Option<usize>,
42        obj: &Bound<'py, PyAny>,
43    ) -> PyResult<()> {
44        v.extend_from_slice(
45            self.python_serde
46                .bind(obj.py())
47                .call_method1(intern!(obj.py(), "get_bytes"), (start_addr, obj))?
48                .downcast::<PyBytes>()?
49                .as_bytes(),
50        );
51        Ok(())
52    }
53
54    fn retrieve<'py>(
55        &mut self,
56        py: Python<'py>,
57        buf: &[u8],
58        offset: usize,
59    ) -> PyResult<(Bound<'py, PyAny>, usize)> {
60        let memory_view = unsafe {
61            Bound::<'py, PyAny>::from_owned_ptr(
62                py,
63                PyMemoryView_FromMemory(
64                    buf.as_ptr() as *mut c_char,
65                    buf.len().try_into().unwrap(),
66                    PyBUF_READ,
67                ),
68            )
69        };
70        self.python_serde
71            .bind(py)
72            .call_method1(intern!(py, "retrieve"), (memory_view, offset))?
73            .extract()
74    }
75}