Emseries now supports both DateTimeTz and Date in the records #43
|
@ -17,7 +17,7 @@ use chrono::SecondsFormat;
|
||||||
use chrono_tz::Etc::UTC;
|
use chrono_tz::Etc::UTC;
|
||||||
use serde::de::{self, Deserialize, Deserializer, Visitor};
|
use serde::de::{self, Deserialize, Deserializer, Visitor};
|
||||||
use serde::ser::{Serialize, Serializer};
|
use serde::ser::{Serialize, Serializer};
|
||||||
use std::fmt;
|
use std::{fmt, str::FromStr};
|
||||||
|
|
||||||
/// This is a wrapper around date time objects, using timezones from the chroon-tz database and
|
/// This is a wrapper around date time objects, using timezones from the chroon-tz database and
|
||||||
/// providing string representation and parsing of the form "<RFC3339> <Timezone Name>", i.e.,
|
/// providing string representation and parsing of the form "<RFC3339> <Timezone Name>", i.e.,
|
||||||
|
@ -54,8 +54,12 @@ impl DateTimeTz {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_str(s: &str) -> Result<DateTimeTz, chrono::ParseError> {
|
impl std::str::FromStr for DateTimeTz {
|
||||||
|
type Err = chrono::ParseError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
let v: Vec<&str> = s.split_terminator(" ").collect();
|
let v: Vec<&str> = s.split_terminator(" ").collect();
|
||||||
if v.len() == 2 {
|
if v.len() == 2 {
|
||||||
let tz = v[1].parse::<chrono_tz::Tz>().unwrap();
|
let tz = v[1].parse::<chrono_tz::Tz>().unwrap();
|
||||||
|
@ -98,11 +102,12 @@ impl<'de> Deserialize<'de> for DateTimeTz {
|
||||||
mod test {
|
mod test {
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
use chrono::TimeZone;
|
use chrono::TimeZone;
|
||||||
use chrono_tz::America::Phoenix;
|
use chrono_tz::America::Phoenix;
|
||||||
use chrono_tz::Etc::UTC;
|
use chrono_tz::Etc::UTC;
|
||||||
use chrono_tz::US::{Arizona, Central};
|
use chrono_tz::US::{Arizona, Central};
|
||||||
use date_time_tz::DateTimeTz;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_creates_timestamp_with_z() {
|
fn it_creates_timestamp_with_z() {
|
||||||
|
|
|
@ -44,11 +44,21 @@ pub enum EmseriesWriteError {
|
||||||
JSONWriteError(serde_json::error::Error),
|
JSONWriteError(serde_json::error::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TimestampFormat {
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
enum Timestamp {
|
||||||
DateTimeTz(DateTimeTz),
|
DateTimeTz(DateTimeTz),
|
||||||
Date(NaiveDate),
|
Date(NaiveDate),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl str::FromStr for Timestamp {
|
||||||
|
type Err = chrono::ParseError;
|
||||||
|
fn from_str(line: &str) -> Result<Self, Self::Err> {
|
||||||
|
DateTimeTz::from_str(line)
|
||||||
|
.map(|dtz| Timestamp::DateTimeTz(dtz))
|
||||||
|
.or(NaiveDate::from_str(line).map(|d| Timestamp::Date(d)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Any element to be put into the database needs to be Recordable. This is the common API that
|
/// Any element to be put into the database needs to be Recordable. This is the common API that
|
||||||
/// will aid in searching and later in indexing records.
|
/// will aid in searching and later in indexing records.
|
||||||
pub trait Recordable {
|
pub trait Recordable {
|
||||||
|
@ -116,6 +126,7 @@ mod test {
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
|
||||||
use self::dimensioned::si::{Kilogram, KG};
|
use self::dimensioned::si::{Kilogram, KG};
|
||||||
|
use super::*;
|
||||||
use super::{Record, Recordable};
|
use super::{Record, Recordable};
|
||||||
use chrono::TimeZone;
|
use chrono::TimeZone;
|
||||||
use chrono_tz::Etc::UTC;
|
use chrono_tz::Etc::UTC;
|
||||||
|
@ -141,10 +152,26 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn timestamp_parses_datetimetz_without_timezone() {
|
||||||
|
assert_eq!(
|
||||||
|
"2003-11-10T06:00:00Z".parse::<Timestamp>().unwrap(),
|
||||||
|
Timestamp::DateTimeTz(DateTimeTz(UTC.ymd(2003, 11, 10).and_hms(6, 0, 0))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn timestamp_parses_date() {
|
||||||
|
assert_eq!(
|
||||||
|
"2023-11-10".parse::<Timestamp>().unwrap(),
|
||||||
|
Timestamp::Date(NaiveDate::from_ymd_opt(2023, 11, 10).unwrap())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const WEIGHT_ENTRY: &str = "{\"data\":{\"weight\":77.79109,\"date\":\"2003-11-10T06:00:00.000000000000Z\"},\"id\":\"3330c5b0-783f-4919-b2c4-8169c38f65ff\"}";
|
const WEIGHT_ENTRY: &str = "{\"data\":{\"weight\":77.79109,\"date\":\"2003-11-10T06:00:00.000000000000Z\"},\"id\":\"3330c5b0-783f-4919-b2c4-8169c38f65ff\"}";
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn legacy_deserialization() {
|
fn legacy_deserialization() {
|
||||||
let rec: Record<WeightRecord> = WEIGHT_ENTRY
|
let rec: Record<WeightRecord> = WEIGHT_ENTRY
|
||||||
.parse()
|
.parse()
|
||||||
.expect("should successfully parse the record");
|
.expect("should successfully parse the record");
|
||||||
|
@ -162,7 +189,7 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn serialization_output() {
|
fn serialization_output() {
|
||||||
let rec = WeightRecord {
|
let rec = WeightRecord {
|
||||||
date: DateTimeTz(UTC.ymd(2003, 11, 10).and_hms(6, 0, 0)),
|
date: DateTimeTz(UTC.ymd(2003, 11, 10).and_hms(6, 0, 0)),
|
||||||
weight: Weight(77.0 * KG),
|
weight: Weight(77.0 * KG),
|
||||||
|
|
Loading…
Reference in New Issue