This commit is contained in:
Dominik Werder
2023-06-20 19:00:08 +02:00
parent 1b3267c1a1
commit 2d566cc9ca
11 changed files with 452 additions and 355 deletions

View File

@@ -47,6 +47,7 @@ pub const CONNECTION_STATUS_DIV: u64 = timeunits::DAY;
pub const TS_MSP_GRID_UNIT: u64 = timeunits::SEC * 10;
pub const TS_MSP_GRID_SPACING: u64 = 6 * 2;
pub const DATETIME_FMT_0MS: &str = "%Y-%m-%dT%H:%M:%SZ";
pub const DATETIME_FMT_3MS: &str = "%Y-%m-%dT%H:%M:%S.%3fZ";
pub const DATETIME_FMT_6MS: &str = "%Y-%m-%dT%H:%M:%S.%6fZ";
pub const DATETIME_FMT_9MS: &str = "%Y-%m-%dT%H:%M:%S.%9fZ";

View File

@@ -6,7 +6,6 @@ use serde::Deserialize;
use serde::Serialize;
use std::fmt;
use std::ops;
use std::time::Duration;
#[derive(Clone, Debug, PartialEq)]
pub struct Datetime(DateTime<FixedOffset>);
@@ -43,24 +42,66 @@ impl Serialize for Datetime {
S: serde::Serializer,
{
use fmt::Write;
use serde::ser::Error;
let val = &self.0;
let mut s = String::with_capacity(64);
write!(&mut s, "{}", val.format("%Y-%m-%dT%H:%M:%S")).map_err(|_| serde::ser::Error::custom("fmt"))?;
write!(&mut s, "{}", val.format("%Y-%m-%dT%H:%M:%S")).map_err(|_| Error::custom("fmt"))?;
let ns = val.timestamp_subsec_nanos();
let mus = val.timestamp_subsec_micros();
if mus % 1000 != 0 {
write!(&mut s, "{}", val.format(".%6f")).map_err(|_| serde::ser::Error::custom("fmt"))?;
if ns % 1000 != 0 {
write!(&mut s, "{}", val.format(".%9f")).map_err(|_| Error::custom("fmt"))?;
} else if mus % 1000 != 0 {
write!(&mut s, "{}", val.format(".%6f")).map_err(|_| Error::custom("fmt"))?;
} else if mus != 0 {
write!(&mut s, "{}", val.format(".%3f")).map_err(|_| serde::ser::Error::custom("fmt"))?;
write!(&mut s, "{}", val.format(".%3f")).map_err(|_| Error::custom("fmt"))?;
}
if val.offset().local_minus_utc() == 0 {
write!(&mut s, "Z").map_err(|_| serde::ser::Error::custom("fmt"))?;
write!(&mut s, "Z").map_err(|_| Error::custom("fmt"))?;
} else {
write!(&mut s, "{}", val.format("%:z")).map_err(|_| serde::ser::Error::custom("fmt"))?;
write!(&mut s, "{}", val.format("%:z")).map_err(|_| Error::custom("fmt"))?;
}
serializer.collect_str(&s)
}
}
mod ser_impl_2 {
use super::Datetime;
use crate::DATETIME_FMT_0MS;
use crate::DATETIME_FMT_3MS;
use crate::DATETIME_FMT_6MS;
use crate::DATETIME_FMT_9MS;
use fmt::Write;
use serde::ser::Error;
use std::fmt;
#[allow(unused)]
fn serialize<S>(obj: &Datetime, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let val = &obj.0;
let mut s = String::with_capacity(64);
write!(&mut s, "{}", val.format("%Y-%m-%dT%H:%M:%S")).map_err(|_| Error::custom("fmt"))?;
let ns = val.timestamp_subsec_nanos();
let s = if ns % 1000 != 0 {
val.format(DATETIME_FMT_9MS)
} else {
let mus = val.timestamp_subsec_micros();
if mus % 1000 != 0 {
val.format(DATETIME_FMT_6MS)
} else {
let ms = val.timestamp_subsec_millis();
if ms != 0 {
val.format(DATETIME_FMT_3MS)
} else {
val.format(DATETIME_FMT_0MS)
}
}
};
serializer.collect_str(&s)
}
}
struct Vis1;
impl<'de> Visitor<'de> for Vis1 {
@@ -125,10 +166,26 @@ fn ser_02() {
.with_ymd_and_hms(2023, 2, 3, 15, 12, 40)
.earliest()
.unwrap()
.checked_add_signed(chrono::Duration::nanoseconds(543432120))
.checked_add_signed(chrono::Duration::nanoseconds(543430000))
.unwrap();
let x = Datetime(x);
let s = serde_json::to_string(&x).unwrap();
assert_eq!(s, r#""2023-02-03T15:12:40.543432Z""#);
assert_eq!(s, r#""2023-02-03T15:12:40.543430Z""#);
}
#[test]
fn ser_03() {
use chrono::TimeZone;
let x = FixedOffset::east_opt(0)
.unwrap()
.with_ymd_and_hms(2023, 2, 3, 15, 12, 40)
.earliest()
.unwrap()
.checked_add_signed(chrono::Duration::nanoseconds(543432321))
.unwrap();
let x = Datetime(x);
let s = serde_json::to_string(&x).unwrap();
assert_eq!(s, r#""2023-02-03T15:12:40.543432321Z""#);
}