use pyo3::prelude::*;
use pyo3::types::{PyAny, PyNone};
use keramics_datetime::{
DateTime, FatDate, FatTimeDate, FatTimeDate10Ms, Filetime, PosixTime32, PosixTime64Ns,
};
pub struct PyDateTime {}
impl PyDateTime {
pub fn new(date_time: &DateTime) -> PyResult<Py<PyAny>> {
Python::attach(|py| -> PyResult<_> {
match date_time {
DateTime::FatDate(fat_date) => {
let py_fat_date: PyFatDate = PyFatDate {
fat_date: fat_date.clone(),
};
Ok(Py::new(py, py_fat_date)?.into_any())
}
DateTime::FatTimeDate(fat_time_date) => {
let py_fat_time_date: PyFatTimeDate = PyFatTimeDate {
fat_time_date: fat_time_date.clone(),
};
Ok(Py::new(py, py_fat_time_date)?.into_any())
}
DateTime::FatTimeDate10Ms(fat_time_date) => {
let py_fat_time_date: PyFatTimeDate10Ms = PyFatTimeDate10Ms {
fat_time_date: fat_time_date.clone(),
};
Ok(Py::new(py, py_fat_time_date)?.into_any())
}
DateTime::Filetime(filetime) => {
let py_filetime: PyFiletime = PyFiletime {
filetime: filetime.clone(),
};
Ok(Py::new(py, py_filetime)?.into_any())
}
DateTime::NotSet => {
let py_none: Borrowed<'_, '_, PyNone> = PyNone::get(py);
Ok(py_none.to_owned().unbind().into_any())
}
DateTime::PosixTime32(posix_time) => {
let py_posix_time: PyPosixTime32 = PyPosixTime32 {
posix_time: posix_time.clone(),
};
Ok(Py::new(py, py_posix_time)?.into_any())
}
DateTime::PosixTime64Ns(posix_time) => {
let py_posix_time: PyPosixTime64Ns = PyPosixTime64Ns {
posix_time: posix_time.clone(),
};
Ok(Py::new(py, py_posix_time)?.into_any())
}
_ => {
todo!();
}
}
})
}
}
#[pyclass]
#[pyo3(name = "FatDate")]
#[derive(Clone)]
struct PyFatDate {
fat_date: FatDate,
}
#[pymethods]
impl PyFatDate {
#[getter]
pub fn timestamp(&self) -> PyResult<u32> {
let seconds: u32 = self.fat_date.get_number_of_seconds();
Ok(seconds * 100)
}
}
#[pyclass]
#[pyo3(name = "FatTimeDate")]
#[derive(Clone)]
struct PyFatTimeDate {
fat_time_date: FatTimeDate,
}
#[pymethods]
impl PyFatTimeDate {
#[getter]
pub fn timestamp(&self) -> PyResult<u32> {
let seconds: u32 = self.fat_time_date.get_number_of_seconds();
Ok(seconds * 100)
}
}
#[pyclass]
#[pyo3(name = "FatTimeDate10Ms")]
#[derive(Clone)]
struct PyFatTimeDate10Ms {
fat_time_date: FatTimeDate10Ms,
}
#[pymethods]
impl PyFatTimeDate10Ms {
#[getter]
pub fn timestamp(&self) -> PyResult<u32> {
let (seconds, fraction): (u32, u32) = self.fat_time_date.get_number_of_seconds();
Ok((seconds * 100) + fraction)
}
}
#[pyclass]
#[pyo3(name = "Filetime")]
#[derive(Clone)]
struct PyFiletime {
filetime: Filetime,
}
#[pymethods]
impl PyFiletime {
#[getter]
pub fn timestamp(&self) -> PyResult<u64> {
Ok(self.filetime.timestamp)
}
}
#[pyclass]
#[pyo3(name = "PosixTime32")]
#[derive(Clone)]
struct PyPosixTime32 {
posix_time: PosixTime32,
}
#[pymethods]
impl PyPosixTime32 {
#[getter]
pub fn timestamp(&self) -> PyResult<i32> {
Ok(self.posix_time.timestamp)
}
}
#[pyclass]
#[pyo3(name = "PosixTime64Ns")]
#[derive(Clone)]
struct PyPosixTime64Ns {
posix_time: PosixTime64Ns,
}
#[pymethods]
impl PyPosixTime64Ns {
#[getter]
pub fn fraction(&self) -> PyResult<u32> {
Ok(self.posix_time.fraction)
}
#[getter]
pub fn timestamp(&self) -> PyResult<i64> {
Ok(self.posix_time.timestamp)
}
}
#[pymodule]
pub fn datetime(module: &Bound<'_, PyModule>) -> PyResult<()> {
module.add_class::<PyFatDate>()?;
module.add_class::<PyFatTimeDate>()?;
module.add_class::<PyFatTimeDate10Ms>()?;
module.add_class::<PyFiletime>()?;
module.add_class::<PyPosixTime32>()?;
module.add_class::<PyPosixTime64Ns>()?;
Ok(())
}