dict.rs

Overview

The `dict.rs` file is a core serialization module focused on efficiently converting Python dictionary objects (`dict`) and related structures into a serialized format (typically JSON or similar) using Rust. It is part of a larger serialization framework that integrates tightly with Python's C API (via `pyo3_ffi`) and Rust's `serde` serialization traits.

The file provides multiple serializer implementations tailored for different dictionary scenarios:

It handles a wide variety of Python object types as dictionary values, applying specialized serializers for each type to optimize performance and correctness.


Key Entities and Their Responsibilities

1. ZeroDictSerializer

pub(crate) struct ZeroDictSerializer;

impl ZeroDictSerializer {
    pub const fn new() -> Self {
        Self {}
    }
}

impl Serialize for ZeroDictSerializer {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_bytes(b"{}")
    }
}

2. DictGenericSerializer

pub(crate) struct DictGenericSerializer {
    ptr: *mut pyo3_ffi::PyObject,
    state: SerializerState,
    default: Option<NonNull<pyo3_ffi::PyObject>>,
}

impl DictGenericSerializer {
    pub fn new(
        ptr: *mut pyo3_ffi::PyObject,
        state: SerializerState,
        default: Option<NonNull<pyo3_ffi::PyObject>>,
    ) -> Self { ... }
}

impl Serialize for DictGenericSerializer {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer,
    { ... }
}

3. Dict

pub(crate) struct Dict {
    ptr: *mut pyo3_ffi::PyObject,
    state: SerializerState,
    default: Option<NonNull<pyo3_ffi::PyObject>>,
}

impl Serialize for Dict {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer,
    { ... }
}

4. DictSortedKey

pub(crate) struct DictSortedKey {
    ptr: *mut pyo3_ffi::PyObject,
    state: SerializerState,
    default: Option<NonNull<pyo3_ffi::PyObject>>,
}

impl Serialize for DictSortedKey {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer,
    { ... }
}

5. DictNonStrKey

pub(crate) struct DictNonStrKey {
    ptr: *mut pyo3_ffi::PyObject,
    state: SerializerState,
    default: Option<NonNull<pyo3_ffi::PyObject>>,
}

impl DictNonStrKey {
    fn pyobject_to_string(
        key: *mut pyo3_ffi::PyObject,
        opts: crate::opt::Opt,
    ) -> Result<String, SerializeError> { ... }
}

impl Serialize for DictNonStrKey {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer,
    { ... }
}

Utility Macro: impl_serialize_entry!


Important Implementation Details


Interaction with Other System Components


Usage Example

Assuming you have a Python dictionary object pointer `py_dict_ptr` and a `SerializerState` `state`, you can serialize the dictionary as follows:

let dict_serializer = DictGenericSerializer::new(py_dict_ptr, state, None);
let serialized = serde_json::to_string(&dict_serializer)?;
println!("{}", serialized);

This will serialize the Python dictionary to a JSON string, automatically handling different key types, sorting options, and nested objects.


Visual Diagram: Class Structure and Relationships

classDiagram
    class DictGenericSerializer {
        -ptr: *mut PyObject
        -state: SerializerState
        -default: Option<NonNull<PyObject>>
        +new(ptr, state, default)
        +serialize(serializer)
    }

    class ZeroDictSerializer {
        +new()
        +serialize(serializer)
    }

    class Dict {
        -ptr: *mut PyObject
        -state: SerializerState
        -default: Option<NonNull<PyObject>>
        +serialize(serializer)
    }

    class DictSortedKey {
        -ptr: *mut PyObject
        -state: SerializerState
        -default: Option<NonNull<PyObject>>
        +serialize(serializer)
    }

    class DictNonStrKey {
        -ptr: *mut PyObject
        -state: SerializerState
        -default: Option<NonNull<PyObject>>
        +pyobject_to_string(key, opts)
        +serialize(serializer)
    }

    DictGenericSerializer --> ZeroDictSerializer : uses when dict empty
    DictGenericSerializer --> Dict : delegates serialize (string keys, no sort)
    DictGenericSerializer --> DictNonStrKey : delegates serialize (non-str keys)
    DictGenericSerializer --> DictSortedKey : delegates serialize (sorted keys)

Summary

The `dict.rs` module is a specialized component in the serialization framework designed to efficiently handle Python dictionaries. It intelligently chooses serialization strategies based on dictionary contents and user options, supports a wide variety of Python key and value types, and integrates deeply with Python's C API and Rust's `serde` traits. The code balances performance optimizations (e.g., zero-copy for empty dicts, use of `SmallVec`) with correctness (type checking, error handling), making it a robust solution for dictionary serialization in mixed Python-Rust environments.