use crate::i18n_string;
use crate::tina::data::i18n_string::I18nString;
use crate::tina::data::AppResult;
use crate::tina::i18n::message::system_message::SystemMessage;
#[allow(deprecated)]
use chrono::{Date, DateTime, Local, LocalResult, NaiveDate, NaiveDateTime, NaiveTime, TimeZone};
use std::{
cmp::max,
ops::{Deref, DerefMut},
};
#[allow(deprecated)]
#[derive(Debug, Copy, Clone)]
pub struct LocalDate(pub Date<Local>);
#[derive(Debug, Copy, Clone)]
pub struct LocalDateTime(pub DateTime<Local>);
#[derive(Debug, Copy, Clone)]
pub struct LocalTime(pub NaiveTime);
#[allow(non_upper_case_globals)]
pub const yyyyMMdd: &str = "%Y%m%d";
#[allow(non_upper_case_globals)]
pub const yyyy_MM_dd: &str = "%Y-%m-%d";
#[allow(non_upper_case_globals)]
pub const yyyyMMddHHmmss: &str = "%Y%m%d%H%M%S";
#[allow(non_upper_case_globals)]
pub const yyyyMMddHHmmssSSS: &str = "%Y%m%d%H%M%S%3f";
#[allow(non_upper_case_globals)]
pub const yyyy_MM: &str = "%Y-%m";
#[allow(non_upper_case_globals)]
pub const yyyy: &str = "%Y";
#[allow(non_upper_case_globals)]
pub const yyyyMM: &str = "%Y%m";
#[allow(non_upper_case_globals)]
pub const yyyy_MM_dd_HH: &str = "%Y-%m-%d %H";
#[allow(non_upper_case_globals)]
pub const yyyy_MM_dd_HH_mm: &str = "%Y-%m-%d %H:%M";
#[allow(non_upper_case_globals)]
pub const yyyy_MM_dd_HH_mm_ss: &str = "%Y-%m-%d %H:%M:%S";
#[allow(non_upper_case_globals)]
pub const yyyy_MM_dd_HH_mm_ss_SSS: &str = "%Y-%m-%d %H:%M:%S.%3f";
#[allow(non_upper_case_globals)]
pub const HH_mm_ss: &str = "%H:%M:%S";
#[allow(non_upper_case_globals)]
pub const HH_mm: &str = "%H:%M";
#[allow(non_upper_case_globals)]
pub const mm_ss: &str = "%M:%S";
#[allow(non_upper_case_globals)]
pub const HH_mm_ss_SSS: &str = "%H:%M:%S.%3f";
#[allow(non_upper_case_globals)]
pub const HHmmss: &str = "%H%M%S";
#[allow(non_upper_case_globals)]
pub const HHmmssSSS: &str = "%H%M%S%3f";
pub const DATE_TIME_FORMATS: [&str; 3] = [yyyy_MM_dd_HH_mm_ss_SSS, yyyy_MM_dd_HH_mm_ss, yyyy_MM_dd_HH_mm];
pub const DATE_FORMATS: [&str; 1] = [yyyy_MM_dd];
pub const TIME_FORMATS: [&str; 5] = [HH_mm_ss, HH_mm_ss_SSS, HH_mm, HHmmss, HHmmssSSS];
impl LocalDate {
pub fn now() -> Self {
LocalDate(Local::now().to_date())
}
}
impl LocalDateTime {
pub fn now() -> Self {
LocalDateTime(Local::now())
}
}
impl LocalTime {
pub fn now() -> Self {
LocalTime(Local::now().time())
}
}
pub trait DateExt {
type DateType;
type DateTimeType;
fn parse_from_str(s: &str, format: &str) -> AppResult<Self::DateType>;
fn from_time_millis(millis: i64) -> AppResult<Self::DateType>;
fn to_date_begin(&self) -> Self::DateTimeType;
fn to_date_end(&self) -> Self::DateTimeType;
}
pub trait DateTimeExt {
type DateType;
type DateTimeType;
fn parse_from_str(s: &str, format: &str) -> AppResult<Self::DateTimeType>;
fn from_time_millis(millis: i64) -> AppResult<Self::DateTimeType>;
fn to_date(&self) -> Self::DateType;
fn to_date_begin(&self) -> Self::DateTimeType;
fn to_date_end(&self) -> Self::DateTimeType;
}
pub trait TimeExt {
fn parse_from_str(s: &str, format: &str) -> AppResult<NaiveTime>;
fn from_time_millis(millis: i64) -> AppResult<NaiveTime>;
}
impl Default for LocalDate {
fn default() -> Self {
LocalDate(Local.from_utc_datetime(&NaiveDateTime::default()).to_date())
}
}
impl Default for LocalDateTime {
fn default() -> Self {
LocalDateTime(Local.from_utc_datetime(&NaiveDateTime::default()))
}
}
impl Default for LocalTime {
fn default() -> Self {
LocalTime(Local.from_utc_datetime(&NaiveDateTime::default()).time())
}
}
#[allow(deprecated)]
impl Deref for LocalDate {
type Target = Date<Local>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Deref for LocalDateTime {
type Target = DateTime<Local>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Deref for LocalTime {
type Target = NaiveTime;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for LocalDate {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl DerefMut for LocalDateTime {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl DerefMut for LocalTime {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[allow(deprecated)]
impl DateExt for Date<Local> {
type DateType = Date<Local>;
type DateTimeType = DateTime<Local>;
fn parse_from_str(s: &str, format: &str) -> AppResult<Date<Local>> {
match NaiveDate::parse_from_str(s, format) {
#[allow(deprecated)]
Ok(d) => match Local::from_local_date(&Local, &d).single() {
None => Err(crate::app_system_error!("parse error: str: {}, format: {}", s, format)),
Some(d) => Ok(d),
},
Err(e1) => match NaiveDateTime::parse_from_str(s, format) {
#[allow(deprecated)]
Ok(d) => match Local::from_local_date(&Local, &d.date()).single() {
None => Err(crate::app_system_error!("parse error: {:?}, str: {}, format: {}", e1, s, format)),
Some(d) => Ok(d),
},
Err(_) => Err(crate::app_system_error!("parse error: {:?}, str: {}, format: {}", e1, s, format)),
},
}
}
fn from_time_millis(millis: i64) -> AppResult<Date<Local>> {
let seconds = millis / 1000;
let nsecs = (millis % 1000) * 1_000_000;
let nsecs = if nsecs > 0 { nsecs as u32 } else { 0_u32 };
#[allow(deprecated)]
match Local::from_local_date(&Local, &NaiveDateTime::from_timestamp(seconds, nsecs).date()).single() {
None => Err(crate::app_system_error!("parse error: {}", millis)),
Some(d) => Ok(d),
}
}
fn to_date_begin(&self) -> DateTime<Local> {
#[allow(deprecated)]
self.and_hms_nano(0, 0, 0, 0)
}
fn to_date_end(&self) -> DateTime<Local> {
#[allow(deprecated)]
self.and_hms_nano(23, 59, 59, 999999999)
}
}
impl DateTimeExt for DateTime<Local> {
#[allow(deprecated)]
type DateType = Date<Local>;
type DateTimeType = DateTime<Local>;
fn parse_from_str(s: &str, format: &str) -> AppResult<DateTime<Local>> {
match NaiveDateTime::parse_from_str(s, format) {
Ok(d) => match Local::from_local_datetime(&Local, &d).single() {
None => Err(crate::app_system_error!("parse error: str: {}, format: {}", s, format)),
Some(d) => Ok(d),
},
Err(e1) => Err(crate::app_system_error!("parse error: {:?}, str: {}, format: {}", e1, s, format)),
}
}
fn from_time_millis(millis: i64) -> AppResult<DateTime<Local>> {
let seconds = millis / 1000;
let nsecs = (millis % 1000) * 1_000_000;
let nsecs = if nsecs > 0 { nsecs as u32 } else { 0_u32 };
#[allow(deprecated)]
match Local::from_local_datetime(&Local, &NaiveDateTime::from_timestamp(seconds, nsecs)).single() {
None => Err(crate::app_system_error!("parse error: {}", millis)),
Some(d) => Ok(d),
}
}
#[allow(deprecated)]
fn to_date(&self) -> Date<Local> {
#[allow(deprecated)]
self.date()
}
fn to_date_begin(&self) -> DateTime<Local> {
#[allow(deprecated)]
self.date().and_hms_nano(0, 0, 0, 0)
}
fn to_date_end(&self) -> DateTime<Local> {
#[allow(deprecated)]
self.date().and_hms_nano(23, 59, 59, 999999999)
}
}
impl TimeExt for NaiveTime {
fn parse_from_str(s: &str, format: &str) -> AppResult<NaiveTime> {
match NaiveTime::parse_from_str(s, format) {
Ok(d) => Ok(d),
Err(e1) => Err(crate::app_system_error!("parse error: {:?}, str: {}, format: {}", e1, s, format)),
}
}
fn from_time_millis(millis: i64) -> AppResult<NaiveTime> {
let seconds = millis / 1000;
let nsecs = (millis % 1000) * 1_000_000;
let nsecs = if nsecs > 0 { nsecs as u32 } else { 0_u32 };
#[allow(deprecated)]
Ok(NaiveDateTime::from_timestamp(seconds, nsecs).time())
}
}
#[allow(deprecated)]
impl DateExt for LocalDate {
type DateType = LocalDate;
type DateTimeType = LocalDateTime;
fn parse_from_str(s: &str, format: &str) -> AppResult<Self::DateType> {
Date::<Local>::parse_from_str(s, format).map(LocalDate)
}
fn from_time_millis(millis: i64) -> AppResult<Self::DateType> {
Date::<Local>::from_time_millis(millis).map(LocalDate)
}
fn to_date_begin(&self) -> Self::DateTimeType {
LocalDateTime(self.0.to_date_begin())
}
fn to_date_end(&self) -> Self::DateTimeType {
LocalDateTime(self.0.to_date_end())
}
}
#[allow(deprecated)]
impl DateTimeExt for LocalDateTime {
type DateType = LocalDate;
type DateTimeType = LocalDateTime;
fn parse_from_str(s: &str, format: &str) -> AppResult<Self::DateTimeType> {
DateTime::<Local>::parse_from_str(s, format).map(LocalDateTime)
}
fn from_time_millis(millis: i64) -> AppResult<Self::DateTimeType> {
DateTime::<Local>::from_time_millis(millis).map(LocalDateTime)
}
fn to_date(&self) -> Self::DateType {
LocalDate(self.0.to_date())
}
fn to_date_begin(&self) -> Self::DateTimeType {
LocalDateTime(self.0.to_date_begin())
}
fn to_date_end(&self) -> Self::DateTimeType {
LocalDateTime(self.0.to_date_end())
}
}
pub trait ToNaiveDate {
fn to_naive_date(&self) -> NaiveDate;
}
pub trait ToNaiveDateTime {
fn to_naive_date_time(&self) -> NaiveDateTime;
}
pub trait ToNaiveTime {
fn to_naive_time(&self) -> NaiveTime;
}
pub trait FromNaiveDate {
fn from_naive_date(v: &NaiveDate) -> AppResult<Self>
where
Self: Sized;
}
pub trait FromNaiveDateTime {
fn from_naive_date_time(v: &NaiveDateTime) -> AppResult<Self>
where
Self: Sized;
}
pub trait FromNaiveTime {
fn from_naive_time(v: &NaiveTime) -> AppResult<Self>
where
Self: Sized;
}
impl ToNaiveDate for LocalDate {
fn to_naive_date(&self) -> NaiveDate {
self.naive_local()
}
}
impl ToNaiveDate for NaiveDate {
fn to_naive_date(&self) -> NaiveDate {
*self
}
}
impl ToNaiveDateTime for LocalDateTime {
fn to_naive_date_time(&self) -> NaiveDateTime {
self.naive_local()
}
}
impl ToNaiveDateTime for NaiveDateTime {
fn to_naive_date_time(&self) -> NaiveDateTime {
*self
}
}
impl FromNaiveDate for LocalDate {
fn from_naive_date(v: &NaiveDate) -> AppResult<Self>
where
Self: Sized,
{
#[allow(deprecated)]
match Local.from_local_date(v) {
LocalResult::None => Err(crate::app_system_error!("parse failed: {}", v)),
LocalResult::Single(v) => Ok(Self(v)),
_ => Err(crate::app_system_error!("parse failed: {}", v)),
}
}
}
impl FromNaiveDate for NaiveDate {
fn from_naive_date(v: &NaiveDate) -> AppResult<Self>
where
Self: Sized,
{
Ok(*v)
}
}
impl FromNaiveDateTime for LocalDateTime {
fn from_naive_date_time(v: &NaiveDateTime) -> AppResult<Self>
where
Self: Sized,
{
match Local.from_local_datetime(v) {
LocalResult::None => Err(crate::app_system_error!("parse failed: {}", v)),
LocalResult::Single(v) => Ok(Self(v)),
_ => Err(crate::app_system_error!("parse failed: {}", v)),
}
}
}
impl FromNaiveDateTime for NaiveDateTime {
fn from_naive_date_time(v: &NaiveDateTime) -> AppResult<Self>
where
Self: Sized,
{
Ok(*v)
}
}
pub trait DurationFormat {
fn to_i18n_format(&self) -> I18nString;
}
impl DurationFormat for std::time::Duration {
fn to_i18n_format(&self) -> I18nString {
second_to_i18n_format(self.as_secs() as i64)
}
}
impl DurationFormat for chrono::Duration {
fn to_i18n_format(&self) -> I18nString {
second_to_i18n_format(self.num_seconds())
}
}
fn second_to_i18n_format(mut second: i64) -> I18nString {
let day = match second >= 24 * 60 * 60 {
true => {
let v = second / (24 * 60 * 60);
second %= 24 * 60 * 60;
v
}
false => 0,
};
let hour = match second >= 60 * 60 {
true => {
let v = second / (60 * 60);
second %= 60 * 60;
v
}
false => 0,
};
let minute = match second >= 60 {
true => {
let v = second / (60);
second %= 60;
v
}
false => 0,
};
second = max(second, 0);
if day > 0 {
return i18n_string!(
SystemMessage::LABEL_DAY_HOUR_MINUTE_SECOND,
("day", day),
("hour", hour),
("minute", minute),
("second", second)
);
}
if hour > 0 {
return i18n_string!(SystemMessage::LABEL_HOUR_MINUTE_SECOND, ("hour", hour), ("minute", minute), ("second", second));
}
if minute > 0 {
return i18n_string!(SystemMessage::LABEL_MINUTE_SECOND, ("minute", minute), ("second", second));
}
i18n_string!(SystemMessage::LABEL_SECOND, ("second", second))
}
#[allow(unused_imports)]
mod ser {
use serde::Serialize;
use super::{yyyy_MM_dd, yyyy_MM_dd_HH_mm_ss, DateExt, LocalDate, LocalDateTime};
impl Serialize for LocalDate {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
#[cfg(feature = "bson")]
{
if std::any::type_name::<S>() == std::any::type_name::<bson::ser::Serializer>() {
let bson = bson::DateTime::from_millis(self.to_date_begin().naive_local().timestamp_millis());
return bson.serialize(serializer);
}
}
#[cfg(feature = "rbs")]
{
if std::any::type_name::<S>() == "rbs::value::ext::se::Serializer" {
let value = rbs::value::Value::I64(self.to_date_begin().naive_local().timestamp_millis());
return value.serialize(serializer);
}
}
let value = self.0.format(yyyy_MM_dd).to_string();
value.serialize(serializer)
}
}
impl Serialize for LocalDateTime {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
#[cfg(feature = "bson")]
{
if std::any::type_name::<S>() == std::any::type_name::<bson::ser::Serializer>() {
let bson = bson::DateTime::from_millis(self.naive_local().timestamp_millis());
return bson.serialize(serializer);
}
}
#[cfg(feature = "rbs")]
{
if std::any::type_name::<S>() == "rbs::value::ext::se::Serializer" {
let value = rbs::value::Value::I64(self.naive_local().timestamp_millis());
return value.serialize(serializer);
}
}
let value = self.0.format(yyyy_MM_dd_HH_mm_ss).to_string();
value.serialize(serializer)
}
}
}
#[allow(deprecated)]
mod de {
use super::{yyyy_MM_dd, yyyy_MM_dd_HH_mm_ss, DateExt, DateTimeExt, LocalDate, LocalDateTime};
use chrono::TimeZone;
use serde::{de::Visitor, Deserialize};
struct LocalDateVisitor;
struct LocalDateTimeVisitor;
impl<'de> Visitor<'de> for LocalDateVisitor {
type Value = LocalDate;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("string or number")
}
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Bool(v), &self))
}
fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_i64(v as i64)
}
fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_i64(v as i64)
}
fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_i64(v as i64)
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
let naive_date_time = chrono::NaiveDateTime::from_timestamp_millis(v)
.ok_or_else(|| serde::de::Error::custom(format!("parse value to naive datetime failed: {:?}", v)))?;
let local_date_time = chrono::Local
.from_local_datetime(&naive_date_time)
.single()
.ok_or_else(|| serde::de::Error::custom(format!("parse naive datetime to local failed: {:?}", naive_date_time)))?;
Ok(LocalDate(local_date_time.date()))
}
fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_u64(v as u64)
}
fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_u64(v as u64)
}
fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_u64(v as u64)
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_i64(v as i64)
}
fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_f64(v as f64)
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Float(v), &self))
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
let value = chrono::Date::<chrono::Local>::parse_from_str(v, yyyy_MM_dd).map_err(|err| serde::de::Error::custom(err))?;
Ok(LocalDate(value))
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_str(v)
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_str(&v)
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
let _ = v;
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Bytes(v), &self))
}
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_bytes(v)
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_bytes(&v)
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Option, &self))
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
let _ = deserializer;
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Option, &self))
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Unit, &self))
}
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
let _ = deserializer;
Err(serde::de::Error::invalid_type(serde::de::Unexpected::NewtypeStruct, &self))
}
fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let _ = seq;
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Seq, &self))
}
fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let _ = map;
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Map, &self))
}
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: serde::de::EnumAccess<'de>,
{
let _ = data;
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Enum, &self))
}
fn __private_visit_untagged_option<D>(self, _: D) -> Result<Self::Value, ()>
where
D: serde::Deserializer<'de>,
{
Err(())
}
}
impl<'de> Visitor<'de> for LocalDateTimeVisitor {
type Value = LocalDateTime;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("string or number")
}
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Bool(v), &self))
}
fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_i64(v as i64)
}
fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_i64(v as i64)
}
fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_i64(v as i64)
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
let naive_date_time = chrono::NaiveDateTime::from_timestamp_millis(v)
.ok_or_else(|| serde::de::Error::custom(format!("parse value to naive datetime failed: {:?}", v)))?;
let local_date_time = chrono::Local
.from_local_datetime(&naive_date_time)
.single()
.ok_or_else(|| serde::de::Error::custom(format!("parse naive datetime to local failed: {:?}", naive_date_time)))?;
Ok(LocalDateTime(local_date_time))
}
fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_u64(v as u64)
}
fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_u64(v as u64)
}
fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_u64(v as u64)
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_i64(v as i64)
}
fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_f64(v as f64)
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Float(v), &self))
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
let value =
chrono::DateTime::<chrono::Local>::parse_from_str(v, yyyy_MM_dd_HH_mm_ss).map_err(|err| serde::de::Error::custom(err))?;
Ok(LocalDateTime(value))
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_str(v)
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_str(&v)
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
let _ = v;
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Bytes(v), &self))
}
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_bytes(v)
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_bytes(&v)
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Option, &self))
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
let _ = deserializer;
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Option, &self))
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Unit, &self))
}
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
let _ = deserializer;
Err(serde::de::Error::invalid_type(serde::de::Unexpected::NewtypeStruct, &self))
}
fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let _ = seq;
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Seq, &self))
}
fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let _ = map;
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Map, &self))
}
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: serde::de::EnumAccess<'de>,
{
let _ = data;
Err(serde::de::Error::invalid_type(serde::de::Unexpected::Enum, &self))
}
fn __private_visit_untagged_option<D>(self, _: D) -> Result<Self::Value, ()>
where
D: serde::Deserializer<'de>,
{
Err(())
}
}
impl<'de> Deserialize<'de> for LocalDate {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[cfg(feature = "bson")]
{
if std::any::type_name::<D>() == std::any::type_name::<bson::de::Deserializer>() {
let bson = bson::DateTime::deserialize(deserializer)?;
let naive_date_time = chrono::NaiveDateTime::from_timestamp_millis(bson.timestamp_millis())
.ok_or_else(|| serde::de::Error::custom(format!("parse bson datetime to naive datetime failed: {:?}", bson)))?;
let local_date_time = chrono::Local
.from_local_datetime(&naive_date_time)
.single()
.ok_or_else(|| serde::de::Error::custom(format!("parse naive datetime to local failed: {:?}", naive_date_time)))?;
return Ok(LocalDate(local_date_time.date()));
}
}
deserializer.deserialize_any(LocalDateVisitor)
}
}
impl<'de> Deserialize<'de> for LocalDateTime {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[cfg(feature = "bson")]
{
if std::any::type_name::<D>() == std::any::type_name::<bson::de::Deserializer>() {
let bson = bson::DateTime::deserialize(deserializer)?;
let naive_date_time = chrono::NaiveDateTime::from_timestamp_millis(bson.timestamp_millis())
.ok_or_else(|| serde::de::Error::custom(format!("parse bson datetime to naive datetime failed: {:?}", bson)))?;
let local_date_time = chrono::Local
.from_local_datetime(&naive_date_time)
.single()
.ok_or_else(|| serde::de::Error::custom(format!("parse naive datetime to local failed: {:?}", naive_date_time)))?;
return Ok(LocalDateTime(local_date_time));
}
}
deserializer.deserialize_any(LocalDateTimeVisitor)
}
}
}
#[allow(unused, missing_docs)]
pub mod serde_date {
use crate::tina::data::date_time::{yyyy_MM_dd, yyyy_MM_dd_HH_mm_ss, FromNaiveDate, ToNaiveDate};
use chrono::{NaiveDate, NaiveDateTime, ParseResult};
use serde::{Deserialize, Deserializer, Serializer};
const DATE_FORMAT: &str = yyyy_MM_dd;
const DATE_TIME_FORMAT: &str = yyyy_MM_dd_HH_mm_ss;
pub fn serialize<S, V>(v: &V, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
V: ToNaiveDate,
{
serializer.serialize_str(v.to_naive_date().format(DATE_FORMAT).to_string().as_str())
}
pub fn deserialize<'de, D, V>(deserializer: D) -> std::result::Result<V, D::Error>
where
D: Deserializer<'de>,
V: FromNaiveDate,
{
let s = String::deserialize(deserializer)?;
match NaiveDate::parse_from_str(&s, DATE_FORMAT) {
Ok(v) => V::from_naive_date(&v).map_err(serde::de::Error::custom),
Err(_) => match NaiveDateTime::parse_from_str(&s, DATE_TIME_FORMAT) {
Ok(v) => V::from_naive_date(&v.date()).map_err(serde::de::Error::custom),
Err(err) => Err(serde::de::Error::custom(err)),
},
}
}
}
#[allow(unused, missing_docs)]
pub mod serde_date_option {
use crate::tina::data::date_time::{yyyy_MM_dd, yyyy_MM_dd_HH_mm_ss, FromNaiveDate, ToNaiveDate};
use chrono::{NaiveDate, NaiveDateTime};
use serde::{Deserialize, Deserializer, Serializer};
const DATE_FORMAT: &str = yyyy_MM_dd;
const DATE_TIME_FORMAT: &str = yyyy_MM_dd_HH_mm_ss;
pub fn serialize<S, V>(v: &Option<V>, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
V: ToNaiveDate,
{
match v.as_ref() {
None => serializer.serialize_none(),
Some(v) => serializer.serialize_str(v.to_naive_date().format(DATE_FORMAT).to_string().as_str()),
}
}
pub fn deserialize<'de, D, V>(deserializer: D) -> std::result::Result<Option<V>, D::Error>
where
D: Deserializer<'de>,
V: FromNaiveDate,
{
let s = Option::<String>::deserialize(deserializer)?;
match s {
None => Ok(None),
Some(s) => match NaiveDate::parse_from_str(&s, DATE_FORMAT) {
Ok(v) => Ok(Some(V::from_naive_date(&v).map_err(serde::de::Error::custom)?)),
Err(_) => match NaiveDateTime::parse_from_str(&s, DATE_TIME_FORMAT) {
Ok(v) => Ok(Some(V::from_naive_date(&v.date()).map_err(serde::de::Error::custom)?)),
Err(err) => Err(serde::de::Error::custom(err)),
},
},
}
}
}
#[allow(unused, missing_docs)]
pub mod serde_date_time {
use crate::tina::data::date_time::{yyyy_MM_dd, yyyy_MM_dd_HH_mm_ss, FromNaiveDateTime, ToNaiveDateTime};
use chrono::{NaiveDate, NaiveDateTime};
use serde::{Deserialize, Deserializer, Serializer};
const DATE_FORMAT: &str = yyyy_MM_dd;
const DATE_TIME_FORMAT: &str = yyyy_MM_dd_HH_mm_ss;
pub fn serialize<S, V>(v: &V, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
V: ToNaiveDateTime,
{
serializer.serialize_str(v.to_naive_date_time().format(DATE_TIME_FORMAT).to_string().as_str())
}
pub fn deserialize<'de, D, V>(deserializer: D) -> std::result::Result<V, D::Error>
where
D: Deserializer<'de>,
V: FromNaiveDateTime,
{
let s = String::deserialize(deserializer)?;
match NaiveDateTime::parse_from_str(&s, DATE_TIME_FORMAT) {
Ok(v) => V::from_naive_date_time(&v).map_err(serde::de::Error::custom),
Err(_) => match NaiveDate::parse_from_str(&s, DATE_FORMAT) {
#[allow(deprecated)]
Ok(v) => V::from_naive_date_time(&v.and_hms_nano(0, 0, 0, 0)).map_err(serde::de::Error::custom),
Err(err) => Err(serde::de::Error::custom(err)),
},
}
}
}
#[allow(unused, missing_docs)]
pub mod serde_date_time_option {
use crate::tina::data::date_time::{yyyy_MM_dd, yyyy_MM_dd_HH_mm_ss, FromNaiveDateTime, ToNaiveDateTime};
use chrono::{NaiveDate, NaiveDateTime};
use serde::{Deserialize, Deserializer, Serializer};
const DATE_FORMAT: &str = yyyy_MM_dd;
const DATE_TIME_FORMAT: &str = yyyy_MM_dd_HH_mm_ss;
pub fn serialize<S, V>(v: &Option<V>, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
V: ToNaiveDateTime,
{
match v.as_ref() {
None => serializer.serialize_none(),
Some(v) => serializer.serialize_str(v.to_naive_date_time().format(DATE_TIME_FORMAT).to_string().as_str()),
}
}
pub fn deserialize<'de, D, V>(deserializer: D) -> std::result::Result<Option<V>, D::Error>
where
D: Deserializer<'de>,
V: FromNaiveDateTime,
{
let s = Option::<String>::deserialize(deserializer)?;
match s {
None => Ok(None),
Some(s) => match NaiveDateTime::parse_from_str(&s, DATE_TIME_FORMAT) {
Ok(v) => Ok(Some(V::from_naive_date_time(&v).map_err(serde::de::Error::custom)?)),
Err(_) => match NaiveDate::parse_from_str(&s, DATE_FORMAT) {
#[allow(deprecated)]
Ok(v) => Ok(Some(V::from_naive_date_time(&v.and_hms_nano(0, 0, 0, 0)).map_err(serde::de::Error::custom)?)),
Err(err) => Err(serde::de::Error::custom(err)),
},
},
}
}
}
#[allow(unused, missing_docs)]
pub mod serde_date_time_millis {
use crate::tina::data::date_time::{yyyy_MM_dd, yyyy_MM_dd_HH_mm_ss, yyyy_MM_dd_HH_mm_ss_SSS, FromNaiveDateTime, ToNaiveDateTime};
use chrono::{NaiveDate, NaiveDateTime, ParseResult};
use serde::{Deserialize, Deserializer, Serializer};
const DATE_FORMAT: &str = yyyy_MM_dd;
const DATE_TIME_FORMAT: &str = yyyy_MM_dd_HH_mm_ss;
const DATE_TIME_MILLIS_FORMAT: &str = yyyy_MM_dd_HH_mm_ss_SSS;
pub fn serialize<S, V>(v: &V, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
V: ToNaiveDateTime,
{
serializer.serialize_str(v.to_naive_date_time().format(DATE_TIME_MILLIS_FORMAT).to_string().as_str())
}
pub fn deserialize<'de, D, V>(deserializer: D) -> std::result::Result<V, D::Error>
where
D: Deserializer<'de>,
V: FromNaiveDateTime,
{
let s = String::deserialize(deserializer)?;
match NaiveDateTime::parse_from_str(&s, DATE_TIME_MILLIS_FORMAT) {
Ok(v) => V::from_naive_date_time(&v).map_err(serde::de::Error::custom),
Err(_) => match NaiveDateTime::parse_from_str(&s, DATE_TIME_FORMAT) {
Ok(v) => V::from_naive_date_time(&v).map_err(serde::de::Error::custom),
Err(_) => match NaiveDate::parse_from_str(&s, DATE_FORMAT) {
#[allow(deprecated)]
Ok(v) => V::from_naive_date_time(&v.and_hms_nano(0, 0, 0, 0)).map_err(serde::de::Error::custom),
Err(err) => Err(serde::de::Error::custom(err)),
},
},
}
}
}
#[allow(unused, missing_docs)]
pub mod serde_date_time_millis_option {
use crate::tina::data::date_time::{yyyy_MM_dd, yyyy_MM_dd_HH_mm_ss, yyyy_MM_dd_HH_mm_ss_SSS, FromNaiveDateTime, ToNaiveDateTime};
use chrono::{NaiveDate, NaiveDateTime};
use serde::{Deserialize, Deserializer, Serializer};
const DATE_FORMAT: &str = yyyy_MM_dd;
const DATE_TIME_FORMAT: &str = yyyy_MM_dd_HH_mm_ss;
const DATE_TIME_MILLIS_FORMAT: &str = yyyy_MM_dd_HH_mm_ss_SSS;
pub fn serialize<S, V>(v: &Option<V>, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
V: ToNaiveDateTime,
{
match v.as_ref() {
None => serializer.serialize_none(),
Some(v) => serializer.serialize_str(v.to_naive_date_time().format(DATE_TIME_MILLIS_FORMAT).to_string().as_str()),
}
}
pub fn deserialize<'de, D, V>(deserializer: D) -> std::result::Result<Option<V>, D::Error>
where
D: Deserializer<'de>,
V: FromNaiveDateTime,
{
let s = Option::<String>::deserialize(deserializer)?;
match s {
None => Ok(None),
Some(s) => match NaiveDateTime::parse_from_str(&s, DATE_TIME_MILLIS_FORMAT) {
Ok(v) => Ok(Some(V::from_naive_date_time(&v).map_err(serde::de::Error::custom)?)),
Err(_) => match NaiveDateTime::parse_from_str(&s, DATE_TIME_FORMAT) {
Ok(v) => Ok(Some(V::from_naive_date_time(&v).map_err(serde::de::Error::custom)?)),
Err(_) => match NaiveDate::parse_from_str(&s, DATE_FORMAT) {
#[allow(deprecated)]
Ok(v) => Ok(Some(V::from_naive_date_time(&v.and_hms_nano(0, 0, 0, 0)).map_err(serde::de::Error::custom)?)),
Err(err) => Err(serde::de::Error::custom(err)),
},
},
},
}
}
}
#[allow(unused, missing_docs)]
pub mod serde_time {
use crate::tina::data::date_time::{FromNaiveTime, HH_mm_ss, ToNaiveTime};
use chrono::NaiveTime;
use serde::{Deserialize, Deserializer, Serializer};
const FORMAT: &str = HH_mm_ss;
pub fn serialize<S, V>(v: &V, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
V: ToNaiveTime,
{
serializer.serialize_str(v.to_naive_time().format(FORMAT).to_string().as_str())
}
pub fn deserialize<'de, D, V>(deserializer: D) -> std::result::Result<V, D::Error>
where
D: Deserializer<'de>,
V: FromNaiveTime,
{
let s = String::deserialize(deserializer)?;
let v = NaiveTime::parse_from_str(&s, FORMAT).map_err(serde::de::Error::custom)?;
V::from_naive_time(&v).map_err(serde::de::Error::custom)
}
}
#[allow(unused, missing_docs)]
pub mod serde_time_option {
use crate::tina::data::date_time::{FromNaiveTime, HH_mm_ss, ToNaiveTime};
use chrono::NaiveTime;
use serde::{Deserialize, Deserializer, Serializer};
const FORMAT: &str = HH_mm_ss;
pub fn serialize<S, V>(v: &Option<V>, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
V: ToNaiveTime,
{
match v.as_ref() {
None => serializer.serialize_none(),
Some(v) => serializer.serialize_str(v.to_naive_time().format(FORMAT).to_string().as_str()),
}
}
pub fn deserialize<'de, D, V>(deserializer: D) -> std::result::Result<Option<V>, D::Error>
where
D: Deserializer<'de>,
V: FromNaiveTime,
{
let s = Option::<String>::deserialize(deserializer)?;
match s {
None => Ok(None),
Some(s) => {
let v = NaiveTime::parse_from_str(&s, FORMAT).map_err(serde::de::Error::custom)?;
let v = V::from_naive_time(&v).map_err(serde::de::Error::custom)?;
Ok(Some(v))
}
}
}
}