pyany_serde/pyany_serde_impl/
dict_serde.rs

1use pyo3::prelude::*;
2use pyo3::types::PyDict;
3
4use crate::{
5    communication::{append_usize, append_usize_vec, retrieve_usize},
6    PyAnySerde,
7};
8
9#[derive(Clone)]
10pub struct DictSerde {
11    pub keys_serde: Box<dyn PyAnySerde>,
12    pub values_serde: Box<dyn PyAnySerde>,
13}
14
15impl PyAnySerde for DictSerde {
16    fn append<'py>(
17        &mut self,
18        buf: &mut [u8],
19        offset: usize,
20        obj: &Bound<'py, PyAny>,
21    ) -> PyResult<usize> {
22        let dict = obj.downcast::<PyDict>()?;
23        let mut offset = append_usize(buf, offset, dict.len());
24        for (key, value) in dict.iter() {
25            offset = self.keys_serde.append(buf, offset, &key)?;
26            offset = self.values_serde.append(buf, offset, &value)?;
27        }
28        Ok(offset)
29    }
30
31    fn append_vec<'py>(
32        &mut self,
33        v: &mut Vec<u8>,
34        start_addr: Option<usize>,
35        obj: &Bound<'py, PyAny>,
36    ) -> PyResult<()> {
37        let dict = obj.downcast::<PyDict>()?;
38        append_usize_vec(v, dict.len());
39        for (key, value) in dict.iter() {
40            self.keys_serde.append_vec(v, start_addr, &key)?;
41            self.values_serde.append_vec(v, start_addr, &value)?;
42        }
43        Ok(())
44    }
45
46    fn retrieve<'py>(
47        &mut self,
48        py: Python<'py>,
49        buf: &[u8],
50        offset: usize,
51    ) -> PyResult<(Bound<'py, PyAny>, usize)> {
52        let dict = PyDict::new(py);
53        let (n_items, mut offset) = retrieve_usize(buf, offset)?;
54        for _ in 0..n_items {
55            let key;
56            (key, offset) = self.keys_serde.retrieve(py, buf, offset)?;
57            let value;
58            (value, offset) = self.values_serde.retrieve(py, buf, offset)?;
59            dict.set_item(key, value)?;
60        }
61        Ok((dict.into_any(), offset))
62    }
63}