1use crate::PyCapsule_Import;
8use crate::{PyObject, PyObject_TypeCheck, PyTypeObject, Py_TYPE};
9use std::ffi::c_char;
10use std::ffi::c_int;
11use std::ptr;
12use std::sync::Once;
13use std::{cell::UnsafeCell, ffi::CStr};
14use {crate::Py_hash_t, std::ffi::c_uchar};
15const _PyDateTime_DATE_DATASIZE: usize = 4;
17const _PyDateTime_TIME_DATASIZE: usize = 6;
18const _PyDateTime_DATETIME_DATASIZE: usize = 10;
19
20#[repr(C)]
21#[derive(Debug)]
22pub struct PyDateTime_Delta {
24 pub ob_base: PyObject,
25 pub hashcode: Py_hash_t,
26 pub days: c_int,
27 pub seconds: c_int,
28 pub microseconds: c_int,
29}
30
31#[repr(C)]
35#[derive(Debug)]
36pub struct _PyDateTime_BaseTime {
38 pub ob_base: PyObject,
39 pub hashcode: Py_hash_t,
40 pub hastzinfo: c_char,
41 pub data: [c_uchar; _PyDateTime_TIME_DATASIZE],
42}
43
44#[repr(C)]
45#[derive(Debug)]
46pub struct PyDateTime_Time {
48 pub ob_base: PyObject,
49 pub hashcode: Py_hash_t,
50 pub hastzinfo: c_char,
51 pub data: [c_uchar; _PyDateTime_TIME_DATASIZE],
52 pub fold: c_uchar,
53 pub tzinfo: *mut PyObject,
58}
59
60#[repr(C)]
61#[derive(Debug)]
62pub struct PyDateTime_Date {
64 pub ob_base: PyObject,
65 pub hashcode: Py_hash_t,
66 pub hastzinfo: c_char,
67 pub data: [c_uchar; _PyDateTime_DATE_DATASIZE],
68}
69
70#[repr(C)]
71#[derive(Debug)]
72pub struct _PyDateTime_BaseDateTime {
74 pub ob_base: PyObject,
75 pub hashcode: Py_hash_t,
76 pub hastzinfo: c_char,
77 pub data: [c_uchar; _PyDateTime_DATETIME_DATASIZE],
78}
79
80#[repr(C)]
81#[derive(Debug)]
82pub struct PyDateTime_DateTime {
84 pub ob_base: PyObject,
85 pub hashcode: Py_hash_t,
86 pub hastzinfo: c_char,
87 pub data: [c_uchar; _PyDateTime_DATETIME_DATASIZE],
88 pub fold: c_uchar,
89 pub tzinfo: *mut PyObject,
94}
95
96#[inline]
100pub unsafe fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int {
103 let data = (*(o as *mut PyDateTime_Date)).data;
105 (c_int::from(data[0]) << 8) | c_int::from(data[1])
106}
107
108#[inline]
109pub unsafe fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int {
112 let data = (*(o as *mut PyDateTime_Date)).data;
113 c_int::from(data[2])
114}
115
116#[inline]
117pub unsafe fn PyDateTime_GET_DAY(o: *mut PyObject) -> c_int {
120 let data = (*(o as *mut PyDateTime_Date)).data;
121 c_int::from(data[3])
122}
123
124macro_rules! _PyDateTime_GET_HOUR {
126 ($o: expr, $offset:expr) => {
127 c_int::from((*$o).data[$offset + 0])
128 };
129}
130
131macro_rules! _PyDateTime_GET_MINUTE {
132 ($o: expr, $offset:expr) => {
133 c_int::from((*$o).data[$offset + 1])
134 };
135}
136
137macro_rules! _PyDateTime_GET_SECOND {
138 ($o: expr, $offset:expr) => {
139 c_int::from((*$o).data[$offset + 2])
140 };
141}
142
143macro_rules! _PyDateTime_GET_MICROSECOND {
144 ($o: expr, $offset:expr) => {
145 (c_int::from((*$o).data[$offset + 3]) << 16)
146 | (c_int::from((*$o).data[$offset + 4]) << 8)
147 | (c_int::from((*$o).data[$offset + 5]))
148 };
149}
150
151macro_rules! _PyDateTime_GET_FOLD {
152 ($o: expr) => {
153 (*$o).fold
154 };
155}
156
157macro_rules! _PyDateTime_GET_TZINFO {
158 ($o: expr) => {
159 if (*$o).hastzinfo != 0 {
160 (*$o).tzinfo
161 } else {
162 $crate::Py_None()
163 }
164 };
165}
166
167#[inline]
169pub unsafe fn PyDateTime_DATE_GET_HOUR(o: *mut PyObject) -> c_int {
172 _PyDateTime_GET_HOUR!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE)
173}
174
175#[inline]
176pub unsafe fn PyDateTime_DATE_GET_MINUTE(o: *mut PyObject) -> c_int {
179 _PyDateTime_GET_MINUTE!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE)
180}
181
182#[inline]
183pub unsafe fn PyDateTime_DATE_GET_SECOND(o: *mut PyObject) -> c_int {
186 _PyDateTime_GET_SECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE)
187}
188
189#[inline]
190pub unsafe fn PyDateTime_DATE_GET_MICROSECOND(o: *mut PyObject) -> c_int {
193 _PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE)
194}
195
196#[inline]
197pub unsafe fn PyDateTime_DATE_GET_FOLD(o: *mut PyObject) -> c_uchar {
200 _PyDateTime_GET_FOLD!(o as *mut PyDateTime_DateTime)
201}
202
203#[inline]
204pub unsafe fn PyDateTime_DATE_GET_TZINFO(o: *mut PyObject) -> *mut PyObject {
208 _PyDateTime_GET_TZINFO!(o as *mut PyDateTime_DateTime)
209}
210
211#[inline]
213pub unsafe fn PyDateTime_TIME_GET_HOUR(o: *mut PyObject) -> c_int {
216 _PyDateTime_GET_HOUR!((o as *mut PyDateTime_Time), 0)
217}
218
219#[inline]
220pub unsafe fn PyDateTime_TIME_GET_MINUTE(o: *mut PyObject) -> c_int {
223 _PyDateTime_GET_MINUTE!((o as *mut PyDateTime_Time), 0)
224}
225
226#[inline]
227pub unsafe fn PyDateTime_TIME_GET_SECOND(o: *mut PyObject) -> c_int {
230 _PyDateTime_GET_SECOND!((o as *mut PyDateTime_Time), 0)
231}
232
233#[inline]
234pub unsafe fn PyDateTime_TIME_GET_MICROSECOND(o: *mut PyObject) -> c_int {
237 _PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_Time), 0)
238}
239
240#[inline]
241pub unsafe fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_uchar {
244 _PyDateTime_GET_FOLD!(o as *mut PyDateTime_Time)
245}
246
247#[inline]
248pub unsafe fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject {
252 _PyDateTime_GET_TZINFO!(o as *mut PyDateTime_Time)
253}
254
255macro_rules! _access_field {
257 ($obj:expr, $type: ident, $field:ident) => {
258 (*($obj as *mut $type)).$field
259 };
260}
261
262macro_rules! _access_delta_field {
264 ($obj:expr, $field:ident) => {
265 _access_field!($obj, PyDateTime_Delta, $field)
266 };
267}
268
269#[inline]
270pub unsafe fn PyDateTime_DELTA_GET_DAYS(o: *mut PyObject) -> c_int {
277 _access_delta_field!(o, days)
278}
279
280#[inline]
281pub unsafe fn PyDateTime_DELTA_GET_SECONDS(o: *mut PyObject) -> c_int {
288 _access_delta_field!(o, seconds)
289}
290
291#[inline]
292pub unsafe fn PyDateTime_DELTA_GET_MICROSECONDS(o: *mut PyObject) -> c_int {
299 _access_delta_field!(o, microseconds)
300}
301
302#[repr(C)]
303#[derive(Debug, Copy, Clone)]
304pub struct PyDateTime_CAPI {
305 pub DateType: *mut PyTypeObject,
306 pub DateTimeType: *mut PyTypeObject,
307 pub TimeType: *mut PyTypeObject,
308 pub DeltaType: *mut PyTypeObject,
309 pub TZInfoType: *mut PyTypeObject,
310 pub TimeZone_UTC: *mut PyObject,
311 pub Date_FromDate: unsafe extern "C" fn(
312 year: c_int,
313 month: c_int,
314 day: c_int,
315 cls: *mut PyTypeObject,
316 ) -> *mut PyObject,
317 pub DateTime_FromDateAndTime: unsafe extern "C" fn(
318 year: c_int,
319 month: c_int,
320 day: c_int,
321 hour: c_int,
322 minute: c_int,
323 second: c_int,
324 microsecond: c_int,
325 tzinfo: *mut PyObject,
326 cls: *mut PyTypeObject,
327 ) -> *mut PyObject,
328 pub Time_FromTime: unsafe extern "C" fn(
329 hour: c_int,
330 minute: c_int,
331 second: c_int,
332 microsecond: c_int,
333 tzinfo: *mut PyObject,
334 cls: *mut PyTypeObject,
335 ) -> *mut PyObject,
336 pub Delta_FromDelta: unsafe extern "C" fn(
337 days: c_int,
338 seconds: c_int,
339 microseconds: c_int,
340 normalize: c_int,
341 cls: *mut PyTypeObject,
342 ) -> *mut PyObject,
343 pub TimeZone_FromTimeZone:
344 unsafe extern "C" fn(offset: *mut PyObject, name: *mut PyObject) -> *mut PyObject,
345
346 pub DateTime_FromTimestamp: unsafe extern "C" fn(
347 cls: *mut PyTypeObject,
348 args: *mut PyObject,
349 kwargs: *mut PyObject,
350 ) -> *mut PyObject,
351 pub Date_FromTimestamp:
352 unsafe extern "C" fn(cls: *mut PyTypeObject, args: *mut PyObject) -> *mut PyObject,
353 pub DateTime_FromDateAndTimeAndFold: unsafe extern "C" fn(
354 year: c_int,
355 month: c_int,
356 day: c_int,
357 hour: c_int,
358 minute: c_int,
359 second: c_int,
360 microsecond: c_int,
361 tzinfo: *mut PyObject,
362 fold: c_int,
363 cls: *mut PyTypeObject,
364 ) -> *mut PyObject,
365 pub Time_FromTimeAndFold: unsafe extern "C" fn(
366 hour: c_int,
367 minute: c_int,
368 second: c_int,
369 microsecond: c_int,
370 tzinfo: *mut PyObject,
371 fold: c_int,
372 cls: *mut PyTypeObject,
373 ) -> *mut PyObject,
374}
375
376unsafe impl Sync for PyDateTime_CAPI {}
378
379pub const PyDateTime_CAPSULE_NAME: &CStr = c"datetime.datetime_CAPI";
380
381#[inline]
387pub unsafe fn PyDateTimeAPI() -> *mut PyDateTime_CAPI {
388 *PyDateTimeAPI_impl.ptr.get()
389}
390
391pub unsafe fn PyDateTime_IMPORT() {
393 if !PyDateTimeAPI_impl.once.is_completed() {
394 let py_datetime_c_api =
395 PyCapsule_Import(PyDateTime_CAPSULE_NAME.as_ptr(), 1) as *mut PyDateTime_CAPI;
396
397 if py_datetime_c_api.is_null() {
398 return;
399 }
400
401 PyDateTimeAPI_impl.once.call_once(|| {
405 *PyDateTimeAPI_impl.ptr.get() = py_datetime_c_api;
406 });
407 }
408}
409
410#[inline]
411pub unsafe fn PyDateTime_TimeZone_UTC() -> *mut PyObject {
412 (*PyDateTimeAPI()).TimeZone_UTC
413}
414
415#[inline]
421pub unsafe fn PyDate_Check(op: *mut PyObject) -> c_int {
423 PyObject_TypeCheck(op, (*PyDateTimeAPI()).DateType) as c_int
424}
425
426#[inline]
427pub unsafe fn PyDate_CheckExact(op: *mut PyObject) -> c_int {
429 (Py_TYPE(op) == (*PyDateTimeAPI()).DateType) as c_int
430}
431
432#[inline]
433pub unsafe fn PyDateTime_Check(op: *mut PyObject) -> c_int {
435 PyObject_TypeCheck(op, (*PyDateTimeAPI()).DateTimeType) as c_int
436}
437
438#[inline]
439pub unsafe fn PyDateTime_CheckExact(op: *mut PyObject) -> c_int {
441 (Py_TYPE(op) == (*PyDateTimeAPI()).DateTimeType) as c_int
442}
443
444#[inline]
445pub unsafe fn PyTime_Check(op: *mut PyObject) -> c_int {
447 PyObject_TypeCheck(op, (*PyDateTimeAPI()).TimeType) as c_int
448}
449
450#[inline]
451pub unsafe fn PyTime_CheckExact(op: *mut PyObject) -> c_int {
453 (Py_TYPE(op) == (*PyDateTimeAPI()).TimeType) as c_int
454}
455
456#[inline]
457pub unsafe fn PyDelta_Check(op: *mut PyObject) -> c_int {
459 PyObject_TypeCheck(op, (*PyDateTimeAPI()).DeltaType) as c_int
460}
461
462#[inline]
463pub unsafe fn PyDelta_CheckExact(op: *mut PyObject) -> c_int {
465 (Py_TYPE(op) == (*PyDateTimeAPI()).DeltaType) as c_int
466}
467
468#[inline]
469pub unsafe fn PyTZInfo_Check(op: *mut PyObject) -> c_int {
471 PyObject_TypeCheck(op, (*PyDateTimeAPI()).TZInfoType) as c_int
472}
473
474#[inline]
475pub unsafe fn PyTZInfo_CheckExact(op: *mut PyObject) -> c_int {
477 (Py_TYPE(op) == (*PyDateTimeAPI()).TZInfoType) as c_int
478}
479
480pub unsafe fn PyTimeZone_FromOffset(offset: *mut PyObject) -> *mut PyObject {
488 ((*PyDateTimeAPI()).TimeZone_FromTimeZone)(offset, std::ptr::null_mut())
489}
490
491pub unsafe fn PyTimeZone_FromOffsetAndName(
492 offset: *mut PyObject,
493 name: *mut PyObject,
494) -> *mut PyObject {
495 ((*PyDateTimeAPI()).TimeZone_FromTimeZone)(offset, name)
496}
497
498pub unsafe fn PyDateTime_FromTimestamp(args: *mut PyObject) -> *mut PyObject {
499 let f = (*PyDateTimeAPI()).DateTime_FromTimestamp;
500 f((*PyDateTimeAPI()).DateTimeType, args, std::ptr::null_mut())
501}
502
503pub unsafe fn PyDate_FromTimestamp(args: *mut PyObject) -> *mut PyObject {
504 let f = (*PyDateTimeAPI()).Date_FromTimestamp;
505 f((*PyDateTimeAPI()).DateType, args)
506}
507
508struct PyDateTimeAPISingleton {
511 once: Once,
512 ptr: UnsafeCell<*mut PyDateTime_CAPI>,
513}
514unsafe impl Sync for PyDateTimeAPISingleton {}
515
516static PyDateTimeAPI_impl: PyDateTimeAPISingleton = PyDateTimeAPISingleton {
517 once: Once::new(),
518 ptr: UnsafeCell::new(ptr::null_mut()),
519};