mod tosql;
use crate::{ Result, oci::{self, *} };
use std::{ mem, cmp::Ordering };
pub(crate) fn new() -> OCIDate {
OCIDate {
year: 0, month: 1, day: 1, hour: 0, min: 0, sec: 0
}
}
pub(crate) fn to_string(fmt: &str, date: &OCIDate, err: &OCIError) -> Result<String> {
let txt = mem::MaybeUninit::<[u8;128]>::uninit();
let mut txt = unsafe { txt.assume_init() };
let mut txt_len = txt.len() as u32;
oci::date_to_text(err, date, fmt.as_ptr(), fmt.len() as u8, &mut txt_len, txt.as_mut_ptr())?;
let txt = &txt[0..txt_len as usize];
Ok( String::from_utf8_lossy(txt).to_string() )
}
pub(crate) fn from_date<'a>(from: &OCIDate, err: &'a OCIError) -> Result<Date<'a>> {
let date = *from;
Ok( Date { date, err } )
}
pub struct Date<'a> {
date: OCIDate,
err: &'a OCIError,
}
impl<'a> Date<'a> {
pub fn new(err: &'a impl AsRef<OCIError>) -> Self {
Self { date: new(), err: err.as_ref() }
}
pub fn with_date(year: i16, month: u8, day: u8, err: &'a impl AsRef<OCIError>) -> Self {
Self {
date: OCIDate { year, month, day, hour: 0, min: 0, sec: 0 },
err: err.as_ref()
}
}
pub fn with_date_and_time(year: i16, month: u8, day: u8, hour: u8, min: u8, sec: u8, err: &'a impl AsRef<OCIError>) -> Self {
Self {
date: OCIDate { year, month, day, hour, min, sec },
err: err.as_ref()
}
}
pub fn from_string(txt: &str, fmt: &str, err: &'a impl AsRef<OCIError>) -> Result<Self> {
let mut date = mem::MaybeUninit::<OCIDate>::uninit();
oci::date_from_text(err.as_ref(), txt.as_ptr(), txt.len() as u32, fmt.as_ptr(), fmt.len() as u8, date.as_mut_ptr())?;
let date = unsafe { date.assume_init() };
Ok( Self { date, err: err.as_ref() } )
}
pub fn from_sysdate(err: &'a impl AsRef<OCIError>) -> Result<Self> {
let mut date = mem::MaybeUninit::<OCIDate>::uninit();
oci::date_sys_date(err.as_ref(), date.as_mut_ptr())?;
let date = unsafe { date.assume_init() };
Ok( Self { date, err: err.as_ref() } )
}
pub fn from_date(from: &'a Date) -> Result<Self> {
from_date(&from.date, from.err)
}
pub fn date(&self) -> (i16, u8, u8) {
(self.date.year, self.date.month, self.date.day)
}
pub fn set_date(&mut self, year: i16, month: u8, day: u8) {
self.date.year = year;
self.date.month = month;
self.date.day = day;
}
pub fn time(&self) -> (u8, u8, u8) {
(self.date.hour, self.date.min, self.date.sec)
}
pub fn set_time(&mut self, hour: u8, min: u8, sec: u8) {
self.date.hour = hour;
self.date.min = min;
self.date.sec = sec;
}
pub fn date_and_time(&self) -> (i16, u8, u8, u8, u8, u8) {
(self.date.year, self.date.month, self.date.day, self.date.hour, self.date.min, self.date.sec)
}
pub fn set_date_and_time(&mut self, year: i16, month: u8, day: u8, hour: u8, min: u8, sec: u8) {
self.date.year = year;
self.date.month = month;
self.date.day = day;
self.date.hour = hour;
self.date.min = min;
self.date.sec = sec;
}
pub fn to_string(&self, fmt: &str) -> Result<String> {
to_string(fmt, &self.date, self.err)
}
pub fn add_days(&self, num: i32) -> Result<Self> {
let mut date = mem::MaybeUninit::<OCIDate>::uninit();
oci::date_add_days(self.err, &self.date, num, date.as_mut_ptr())?;
let date = unsafe { date.assume_init() };
Ok( Self { date, ..*self } )
}
pub fn add_months(&self, num: i32) -> Result<Self> {
let mut date = mem::MaybeUninit::<OCIDate>::uninit();
oci::date_add_months(self.err, &self.date, num, date.as_mut_ptr())?;
let date = unsafe { date.assume_init() };
Ok( Self { date, ..*self } )
}
pub fn compare(&self, other: &Date) -> Result<Ordering> {
let mut res = 0i32;
oci::date_compare(self.err, &self.date, &other.date, &mut res)?;
Ok(
if res == 0 { Ordering::Equal } else if res < 0 { Ordering::Less } else { Ordering::Greater }
)
}
pub fn days_from(&self, other: &Date) -> Result<i32> {
let mut res = 0i32;
oci::date_days_between(self.err, &self.date, &other.date, &mut res)?;
Ok( res )
}
pub fn month_last_day(&self) -> Result<Self> {
let mut date = mem::MaybeUninit::<OCIDate>::uninit();
oci::date_last_day(self.err, &self.date, date.as_mut_ptr())?;
let date = unsafe { date.assume_init() };
Ok( Self { date, ..*self } )
}
pub fn next_week_day(&self, weekday: &str) -> Result<Self> {
let mut date = mem::MaybeUninit::<OCIDate>::uninit();
oci::date_next_day(self.err, &self.date, weekday.as_ptr(), weekday.len() as u32, date.as_mut_ptr())?;
let date = unsafe { date.assume_init() };
Ok( Self { date, ..*self } )
}
}
impl std::fmt::Debug for Date<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.date.fmt(f)
}
}