use {
crate::{datetime::*, use_m::*},
chrono::{DateTime, FixedOffset, NaiveDate, TimeZone},
mysql::{
prelude::{ConvIr, FromValue},
FromValueError, Value,
},
serde::{Deserialize, Deserializer, Serialize, Serializer},
std::fmt,
};
#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
pub struct SqlDate {
sdate: String,
ndate: NaiveDate,
}
impl SqlDate {
#[allow(dead_code)]
#[inline]
pub fn n(&self) -> &NaiveDate {
&self.ndate
}
#[auto_func_name]
pub fn new(date: String) -> Result<Self, MoreError> {
let ndate = bjtc_sd(&date).m(m!(fname))?;
Ok(Self { ndate, sdate: date })
}
pub fn new_n(date: NaiveDate) -> Self {
let sdate = bjtc_ds(&date);
Self { ndate: date, sdate }
}
#[inline]
pub fn s(&self) -> &String {
&self.sdate
}
#[allow(dead_code)]
#[inline]
pub fn set_n(&mut self, date: NaiveDate) {
self.sdate = bjtc_ds(&date);
self.ndate = date;
}
#[auto_func_name]
#[inline]
pub fn set_s(&mut self, date: String) -> Result<(), MoreError> {
self.ndate = bjtc_sd(&date).m(m!(fname))?;
self.sdate = date;
Ok(())
}
}
impl fmt::Debug for SqlDate {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
self.sdate.fmt(f)
}
}
impl Default for SqlDate {
fn default() -> Self {
Self {
sdate: "2000-01-01".to_string(),
ndate: NaiveDate::from_ymd_opt(2000, 1, 1).unwrap(), }
}
}
impl From<SqlDate> for Value {
fn from(x: SqlDate) -> Value {
Value::from(x.s())
}
}
impl FromValue for SqlDate {
type Intermediate = SqlDateParser;
}
pub struct SqlDateParser {
value: Value,
output: SqlDate,
}
impl ConvIr<SqlDate> for SqlDateParser {
fn commit(self) -> SqlDate {
self.output
}
fn new(value: Value) -> Result<Self, FromValueError> {
let (sdate, ndate) = match value {
Value::Date(y, m, d, _, _, _, _) => match NaiveDate::from_ymd_opt(y as i32, m as u32, d as u32) {
Some(ndate) => {
let sdate = bjtc_ds(&ndate);
(sdate, ndate)
}
None => return Err(FromValueError(value)),
},
_ => {
let sdate = String::from_value_opt(value.clone())?;
let ndate = match bjtc_sd(&sdate) {
Ok(date) => date,
Err(_) => return Err(FromValueError(value)),
};
(sdate, ndate)
}
};
Ok(Self {
value,
output: SqlDate { sdate, ndate },
})
}
fn rollback(self) -> Value {
self.value
}
}
#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
pub struct SqlTime {
stime: String,
ntime: DateTime<FixedOffset>,
}
impl SqlTime {
#[allow(dead_code)]
#[inline]
pub fn n(&self) -> &DateTime<FixedOffset> {
&self.ntime
}
#[auto_func_name]
pub fn new(time: String) -> Result<Self, MoreError> {
let ntime = bjtc_bt(&time).m(m!(fname))?;
Ok(Self { ntime, stime: time })
}
pub fn new_n(time: DateTime<FixedOffset>) -> Self {
let stime = bjtc_tb(&time);
Self { ntime: time, stime }
}
#[inline]
pub fn s(&self) -> &String {
&self.stime
}
#[allow(dead_code)]
#[inline]
pub fn set_n(&mut self, time: DateTime<FixedOffset>) {
self.stime = bjtc_tb(&time);
self.ntime = time;
}
#[auto_func_name]
#[inline]
pub fn set_s(&mut self, time: String) -> Result<(), MoreError> {
self.ntime = bjtc_bt(&time).m(m!(fname))?;
self.stime = time;
Ok(())
}
}
impl fmt::Debug for SqlTime {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
self.stime.fmt(f)
}
}
impl Default for SqlTime {
fn default() -> Self {
Self {
stime: "2000-01-01T00:00:00".to_string(),
ntime: FixedOffset::east_opt(8 * 3600)
.unwrap()
.with_ymd_and_hms(2000, 1, 1, 0, 0, 0)
.unwrap(),
}
}
}
impl From<SqlTime> for Value {
fn from(x: SqlTime) -> Value {
Value::from(x.s())
}
}
impl FromValue for SqlTime {
type Intermediate = SqlTimeParser;
}
impl Serialize for SqlTime {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.stime)
}
}
impl<'de> Deserialize<'de> for SqlTime {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
SqlTime::new(s).map_err(serde::de::Error::custom)
}
}
pub struct SqlTimeParser {
value: Value,
output: SqlTime,
}
impl ConvIr<SqlTime> for SqlTimeParser {
fn commit(self) -> SqlTime {
self.output
}
fn new(value: Value) -> Result<Self, FromValueError> {
let (stime, ntime) = match value {
Value::Date(y, mo, d, h, mi, s, _) => match FixedOffset::east_opt(8 * 3600)
.unwrap()
.with_ymd_and_hms(y as i32, mo as u32, d as u32, h as u32, mi as u32, s as u32)
.single()
{
Some(ntime) => {
let stime = bjtc_tb(&ntime);
(stime, ntime)
}
None => return Err(FromValueError(value)),
},
_ => {
let stime = String::from_value_opt(value.clone())?;
let ntime = match bjtc_bt(&stime) {
Ok(time) => time,
Err(_) => return Err(FromValueError(value)),
};
(stime, ntime)
}
};
Ok(Self {
value,
output: SqlTime { stime, ntime },
})
}
fn rollback(self) -> Value {
self.value
}
}