datetime.rs

Overview

The [datetime.rs](/projects/287/67764) file provides low-level Rust abstractions and serialization utilities for handling Python datetime objects within a Rust-based serialization framework. It primarily deals with the representation and serialization of Python `date`, `time`, and `datetime` objects, interfacing directly with Python's C API through FFI (Foreign Function Interface).

This file implements:

The main goal is to enable efficient and correct serialization of Python datetime objects into string representations while respecting options such as omission of microseconds and correct timezone offset retrieval.


Detailed Explanation of Components

Macros

write_double_digit!

macro_rules! write_double_digit {
    ($buf:ident, $value:ident) => {
        if $value < 10 {
            $buf.put_u8(b'0');
        }
        $buf.put_slice(itoa::Buffer::new().format($value).as_bytes());
    };
}

**Usage example:**

write_double_digit!(buf, 7);  // writes "07"
write_double_digit!(buf, 23); // writes "23"

write_microsecond!

macro_rules! write_microsecond {
    ($buf:ident, $microsecond:ident) => {
        if $microsecond != 0 {
            let mut buf = itoa::Buffer::new();
            let formatted = buf.format($microsecond);
            $buf.put_slice(&[b'.', b'0', b'0', b'0', b'0', b'0', b'0'][..(7 - formatted.len())]);
            $buf.put_slice(formatted.as_bytes());
        }
    };
}

**Example:**

write_microsecond!(buf, 123456); // writes ".123456"
write_microsecond!(buf, 0);      // writes nothing

Structs and Enums

Date

#[repr(transparent)]
pub(crate) struct Date {
    ptr: *mut pyo3_ffi::PyObject,
}

**Key methods:**

**Usage example:**

let date = Date::new(py_date_ptr);
let mut buf = SmallFixedBuffer::new();
date.write_buf(&mut buf);
println!("{}", std::str::from_utf8(buf.as_slice()).unwrap()); // e.g. "2024-04-27"

TimeError

pub(crate) enum TimeError {
    HasTimezone,
}

Time

pub(crate) struct Time {
    ptr: *mut pyo3_ffi::PyObject,
    opts: Opt,
}

**Key methods:**

**Usage example:**

let time = Time::new(py_time_ptr, opts);
let mut buf = SmallFixedBuffer::new();
time.write_buf(&mut buf)?; // May error if tzinfo present
println!("{}", std::str::from_utf8(buf.as_slice()).unwrap()); // e.g. "14:30:00.123456"

DateTime

pub(crate) struct DateTime {
    ptr: *mut pyo3_ffi::PyObject,
    opts: Opt,
}

**Key traits and methods:**

**Important Implementation Details:**


Trait Implementations

DateTimeLike (for DateTime)

This trait defines an interface for extracting datetime-like fields and offset information.


Interaction with Other System Components


Example Usage

Assuming a Python `datetime` object pointer `py_dt_ptr` and serialization options `opts`:

use datetime::DateTime;
use serde_json::to_string;

let dt = DateTime::new(py_dt_ptr, opts);
// Serialize datetime object to JSON string (as ISO 8601 string)
let json_str = to_string(&dt).expect("Serialization failed");
println!("Serialized datetime: {}", json_str);

Visual Diagram

classDiagram
    class Date {
        -ptr: *mut PyObject
        +new(ptr: *mut PyObject) Date
        +write_buf<B: BufMut>(&mut buf)
        +serialize<S: Serializer>(serializer: S) -> Result
    }

    class Time {
        -ptr: *mut PyObject
        -opts: Opt
        +new(ptr: *mut PyObject, opts: Opt) Time
        +write_buf<B: BufMut>(&mut buf) -> Result<(), TimeError>
        +serialize<S: Serializer>(serializer: S) -> Result
    }

    class DateTime {
        -ptr: *mut PyObject
        -opts: Opt
        +new(ptr: *mut PyObject, opts: Opt) DateTime
        +year() -> i32
        +month() -> u8
        +day() -> u8
        +hour() -> u8
        +minute() -> u8
        +second() -> u8
        +microsecond() -> u32
        +nanosecond() -> u32
        +has_tz() -> bool
        +offset() -> Result<Offset, DateTimeError>
        +slow_offset() -> Result<Offset, DateTimeError>
        +serialize<S: Serializer>(serializer: S) -> Result
    }

    DateTime ..|> DateTimeLike
    Date ..|> Serialize
    Time ..|> Serialize
    DateTime ..|> Serialize

Summary

The [datetime.rs](/projects/287/67764) file is a critical module for serializing Python datetime-related objects in Rust, providing:

Its design blends low-level FFI interactions with Rust’s type safety and performance, enabling robust serialization in Python-Rust interop contexts.