Emseries now supports both DateTimeTz and Date in the records #43

Merged
savanni merged 4 commits from emseries/date-based-events into main 2023-05-25 13:07:31 +00:00
2 changed files with 38 additions and 6 deletions
Showing only changes of commit d4a55ccb17 - Show all commits

View File

@ -17,7 +17,7 @@ use chrono::SecondsFormat;
use chrono_tz::Etc::UTC;
use serde::de::{self, Deserialize, Deserializer, Visitor};
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
/// 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();
if v.len() == 2 {
let tz = v[1].parse::<chrono_tz::Tz>().unwrap();
@ -98,11 +102,12 @@ impl<'de> Deserialize<'de> for DateTimeTz {
mod test {
extern crate serde_json;
use super::*;
use chrono::TimeZone;
use chrono_tz::America::Phoenix;
use chrono_tz::Etc::UTC;
use chrono_tz::US::{Arizona, Central};
use date_time_tz::DateTimeTz;
use std::str::FromStr;
#[test]
fn it_creates_timestamp_with_z() {

View File

@ -44,11 +44,21 @@ pub enum EmseriesWriteError {
JSONWriteError(serde_json::error::Error),
}
enum TimestampFormat {
#[derive(Debug, Clone, PartialEq)]
enum Timestamp {
DateTimeTz(DateTimeTz),
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
/// will aid in searching and later in indexing records.
pub trait Recordable {
@ -116,6 +126,7 @@ mod test {
extern crate serde_json;
use self::dimensioned::si::{Kilogram, KG};
use super::*;
use super::{Record, Recordable};
use chrono::TimeZone;
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\"}";
#[test]
pub fn legacy_deserialization() {
fn legacy_deserialization() {
let rec: Record<WeightRecord> = WEIGHT_ENTRY
.parse()
.expect("should successfully parse the record");
@ -162,7 +189,7 @@ mod test {
}
#[test]
pub fn serialization_output() {
fn serialization_output() {
let rec = WeightRecord {
date: DateTimeTz(UTC.ymd(2003, 11, 10).and_hms(6, 0, 0)),
weight: Weight(77.0 * KG),