float.rs
Overview
The `float.rs` file provides a specialized serialization utility for Python floating-point objects (`PyFloat`) within a Rust context, particularly for use with the [serde](https://serde.rs/) serialization framework. It defines a transparent wrapper struct, `FloatSerializer`, that holds a raw pointer to a Python float object and implements the `Serialize` trait to convert the Python float into a Rust `f64` for serialization.
This file is part of a Rust-Python interoperability layer, likely within a project that bridges Rust and Python objects using [PyO3](https://pyo3.rs/), enabling efficient serialization of Python floats into formats supported by serde serializers (e.g., JSON, MessagePack).
Detailed Documentation
Struct: FloatSerializer
#[repr(transparent)]
pub(crate) struct FloatSerializer {
ptr: *mut pyo3_ffi::PyObject,
}
Purpose:
Acts as a thin wrapper around a raw pointer to a PythonPyObjectthat is assumed to represent a Python float (PyFloat). The#[repr(transparent)]attribute ensures thatFloatSerializerhas the same memory layout as the underlying pointer, allowing safe FFI operations.Field:
ptr: *mut pyo3_ffi::PyObject
A raw mutable pointer to a Python object. Expected to point to a validPyFloatobject.
Impl: FloatSerializer
new
pub fn new(ptr: *mut pyo3_ffi::PyObject) -> Self
Description:
Constructs a newFloatSerializerwrapping the provided raw pointer.Parameters:
ptr: A raw mutable pointer to a Python float object (PyFloat).
Returns:
AFloatSerializerinstance encapsulating the pointer.Usage Example:
let py_float_ptr: *mut pyo3_ffi::PyObject = /* obtained from Python/C API */;
let serializer = FloatSerializer::new(py_float_ptr);
Trait Impl: Serialize for FloatSerializer
impl Serialize for FloatSerializer {
#[inline(always)]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_f64(ffi!(PyFloat_AS_DOUBLE(self.ptr)))
}
}
Description:
Implements theserde::Serializetrait forFloatSerializer, enabling it to be serialized directly by any serde-compatible serializer.Method:
serializeParameters:
serializer: An instance implementing theserde::Serializertrait.
Returns:
AResulttype wrapping the serializer's output or an error.Functionality:
Uses the Python C API macroPyFloat_AS_DOUBLE(accessed via theffi!macro) to extract the rawf64value from the Python float pointer. Then, it callsserialize_f64on the provided serializer to serialize this floating-point number.
Important Notes:
The method is marked
#[inline(always)]to encourage the compiler to inline this function for performance.The
ffi!macro is assumed to be a helper macro that allows direct invocation of Python C API functions/macros in Rust.This implementation assumes the pointer is valid and points to a Python float object; no runtime checks are performed here.
Usage Example:
use serde_json;
let py_float_ptr: *mut pyo3_ffi::PyObject = /* pointer from Python */;
let float_serializer = FloatSerializer::new(py_float_ptr);
let json_string = serde_json::to_string(&float_serializer).unwrap();
println!("{}", json_string); // Outputs the float as JSON number, e.g., "3.14"
Important Implementation Details
Use of Raw Pointers:
The struct stores a raw pointer to a Python object. This requires careful management of Python reference counts and lifetime elsewhere in the codebase to avoid dangling pointers or memory safety issues.#[repr(transparent)]:
Ensures thatFloatSerializerhas the same ABI as the raw pointer it wraps. This is crucial for FFI compatibility and potentially for zero-cost abstractions.Serialization Logic:
Directly extracts the floating-point value from the Python float object using the Python C API macroPyFloat_AS_DOUBLEwithout additional overhead or conversions.No Error Handling Inside Serialize:
The code assumes that the pointer is valid and that the contained object is a float. If this assumption fails, undefined behavior may occur. Validation and safety checks are expected to be handled at higher levels.
Interaction With Other Parts of the System
Python FFI Layer:
This file relies on the Python C API via thepyo3_fficrate/module and theffi!macro to access the internal representation of Python float objects.Serialization Framework (
serde):
Integrates with serde by implementing theSerializetrait, enabling seamless serialization of Python float objects into various formats (JSON, YAML, etc.) supported by serde.Higher-Level Python-Rust Bridge Components:
Likely used within a broader context where Python objects are wrapped and managed safely in Rust, with this file specifically responsible for serializing Python float values efficiently.
Visual Diagram
classDiagram
class FloatSerializer {
- ptr: *mut PyObject
+ new(ptr: *mut PyObject) FloatSerializer
+ serialize<S: Serializer>(serializer: S) Result<S::Ok, S::Error>
}
FloatSerializer ..|> Serialize
Summary
`float.rs` is a concise utility file that wraps a raw pointer to a Python float object and provides an efficient serialization implementation by exposing its inner floating-point value to Rust's serde framework. It is a low-level bridge component facilitating data interchange between Python and Rust, especially in contexts requiring serialization of Python floats into Rust-supported formats.
This file's design prioritizes performance and interoperability but assumes upstream safety guarantees regarding pointer validity and object type correctness.