From 3d196d58e6053c7bb70d5365fc54f9e4a60faae0 Mon Sep 17 00:00:00 2001 From: Michael Freeborn Date: Fri, 29 Jul 2022 17:02:52 +0100 Subject: [PATCH 1/4] fix time zone errors --- CHANGELOG.md | 4 + src/calc.rs | 169 +++++++++++++++++++++++++------------------ src/report.rs | 74 +++++++++---------- src/structs.rs | 24 +++--- src/subcommands.rs | 3 +- tests/test_report.rs | 129 ++++++++++++++++++++++++++------- 6 files changed, 249 insertions(+), 154 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2e3e34..53b226b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v0.8.0] - 2022-xx-xx +### Fixed +- More time zone errors... more tests added to prove correctness ([#53](https://github.com/mfreeborn/heliocron/issues/53)) + ## [v0.7.0] - 2022-06-12 ### Fixed - Fixed handling of time zones so that they are now implemented properly ([#41](https://github.com/mfreeborn/heliocron/issues/41)). diff --git a/src/calc.rs b/src/calc.rs index 309545e..9d785b5 100644 --- a/src/calc.rs +++ b/src/calc.rs @@ -3,17 +3,25 @@ use chrono::{DateTime, Duration, FixedOffset, NaiveDateTime, NaiveTime, TimeZone use super::traits::{DateTimeExt, NaiveTimeExt}; use super::{enums, structs}; +/// Convert a chrono::FixedOffset into a deimal float representation. +fn offset_to_decimal_float(offset: &FixedOffset) -> f64 { + offset.local_minus_utc() as f64 / 3600.0 +} + #[derive(Debug, Clone)] -struct SolarCalculationsRow { +pub struct SolarCalculations { + pub date: DateTime, + pub coordinates: structs::Coordinates, + solar_declination: f64, solar_noon_fraction: f64, corrected_solar_elevation_angle: f64, } -impl SolarCalculationsRow { - pub fn new(date: NaiveDateTime, coordinates: structs::Coordinates) -> SolarCalculationsRow { - let time_zone = 0.; - let julian_date: f64 = date.to_julian_date(); +impl SolarCalculations { + pub fn new(date: DateTime, coordinates: structs::Coordinates) -> Self { + let time_zone = offset_to_decimal_float(date.offset()); + let julian_date: f64 = date.naive_utc().to_julian_date(); let julian_century = (julian_date - 2451545.0) / 36525.0; @@ -111,45 +119,18 @@ impl SolarCalculationsRow { let corrected_solar_elevation_angle = solar_elevation_angle + atmospheric_refraction; - SolarCalculationsRow { + Self { + date, + coordinates, solar_declination, solar_noon_fraction, corrected_solar_elevation_angle, } } -} - -#[derive(Debug, Clone)] -pub struct SolarCalculations { - pub date: DateTime, - pub coordinates: structs::Coordinates, - - midday_calculations: SolarCalculationsRow, -} - -impl SolarCalculations { - pub fn new( - date: DateTime, - coordinates: structs::Coordinates, - ) -> SolarCalculations { - // Using `naive_local()` gives us the correct date when the offset would push the date - // either one day ahead or one day before. - let local_date = date.naive_local(); - let midday_calculations = SolarCalculationsRow::new(local_date, coordinates); - - SolarCalculations { - date, - coordinates, - midday_calculations, - } - } pub fn get_solar_noon(&self) -> structs::EventTime { - let solar_noon = - self.day_fraction_to_datetime(self.midday_calculations.solar_noon_fraction); - structs::EventTime { - datetime: Some(solar_noon), - } + let solar_noon = self.day_fraction_to_datetime(self.solar_noon_fraction); + structs::EventTime::new(Some(solar_noon)) } fn day_fraction_to_datetime(&self, mut day_fraction: f64) -> DateTime { @@ -175,34 +156,21 @@ impl SolarCalculations { // Creating the datetime using the UTC offset, before updating the timezone to the one set by // the user, is necessary so that the calculations and timezones all match up. // These are all safe to unwrap because we are taking the values from a valid NaiveTime. - Utc.from_local_datetime( - &date - .with_hour(time.hour()) - .unwrap() - .with_minute(time.minute()) - .unwrap() - .with_second(time.second()) - .unwrap(), - ) - .unwrap() - .with_timezone(self.date.offset()) + + self.date + .offset() + .from_local_date(&date.date()) + .and_time(time) + .unwrap() } fn calculate_hour_angle(&self, degrees_below_horizon: f64) -> Option { let event_angle = degrees_below_horizon + 90.0; let hour_angle = (((event_angle.to_radians().cos() / (self.coordinates.latitude.to_radians().cos() - * self - .midday_calculations - .solar_declination - .to_radians() - .cos())) + * self.solar_declination.to_radians().cos())) - self.coordinates.latitude.to_radians().tan() - * self - .midday_calculations - .solar_declination - .to_radians() - .tan()) + * self.solar_declination.to_radians().tan()) .acos()) .to_degrees(); @@ -263,21 +231,15 @@ impl SolarCalculations { match hour_angle { Some(hour_angle) => { let day_fraction = match time_of_day { - enums::TimeOfDay::AM => { - self.midday_calculations.solar_noon_fraction - (hour_angle / 360.0) - } - enums::TimeOfDay::PM => { - self.midday_calculations.solar_noon_fraction + (hour_angle / 360.0) - } + enums::TimeOfDay::AM => self.solar_noon_fraction - (hour_angle / 360.0), + enums::TimeOfDay::PM => self.solar_noon_fraction + (hour_angle / 360.0), }; let event_time = self.day_fraction_to_datetime(day_fraction); - structs::EventTime { - datetime: Some(event_time), - } + structs::EventTime::new(Some(event_time)) } - None => structs::EventTime { datetime: None }, + None => structs::EventTime::new(None), } } @@ -286,7 +248,7 @@ impl SolarCalculations { let sunrise = self.calculate_event_time(enums::Event::new("sunrise", None).unwrap()); let sunset = self.calculate_event_time(enums::Event::new("sunset", None).unwrap()); - match (sunrise.datetime, sunset.datetime) { + match (sunrise.0, sunset.0) { (Some(sunrise), Some(sunset)) => sunset - sunrise, _ => { let max_solar_elevation = self.calculate_max_solar_elevation(); @@ -305,16 +267,79 @@ impl SolarCalculations { /// the south, corrected for atmospheric refraction. fn calculate_max_solar_elevation(&self) -> f64 { // Safe to unwrap as there is always a solar noon. - let date = self.get_solar_noon().datetime.unwrap().naive_utc(); - SolarCalculationsRow::new(date, self.coordinates).corrected_solar_elevation_angle + let date = self.get_solar_noon().0.unwrap(); + SolarCalculations::new(date, self.coordinates).corrected_solar_elevation_angle } } #[cfg(test)] mod tests { - // note that the correctness of the maths in this module is tested elsewhere + use crate::structs::{Coordinates, Latitude, Longitude}; + use super::*; + #[test] + fn test_offset_to_decimal_float() { + assert_eq!(offset_to_decimal_float(&FixedOffset::east(3600)), 1.0); + assert_eq!(offset_to_decimal_float(&FixedOffset::east(-3600)), -1.0); + #[rustfmt::skip] + assert_eq!(offset_to_decimal_float(&FixedOffset::east(-3600 * 10)), -10.0); + #[rustfmt::skip] + assert_eq!(offset_to_decimal_float(&FixedOffset::east((3600.0 * 10.5) as i32)), 10.5); + } + + #[test] + fn test_midday_calcs_zero_offset() { + let date = FixedOffset::east(0).ymd(2022, 7, 29).and_hms(12, 0, 0); + let coords = Coordinates { + latitude: Latitude(56.8197), + longitude: Longitude(-5.1047), + }; + + let calcs = SolarCalculations::new(date, coords); + assert_eq!(calcs.solar_noon_fraction, 0.5186937689277599); + } + + #[test] + fn test_midday_calcs_small_offset() { + let date = FixedOffset::east(3600).ymd(2022, 7, 29).and_hms(12, 0, 0); + let coords = Coordinates { + latitude: Latitude(56.8197), + longitude: Longitude(-5.1047), + }; + + let calcs = SolarCalculations::new(date, coords); + assert_eq!(calcs.solar_noon_fraction, 0.5603613849259489); + } + + #[test] + fn test_midday_calcs_large_pos_offset() { + let date = FixedOffset::east(3600 * 11) + .ymd(2022, 7, 29) + .and_hms(12, 0, 0); + let coords = Coordinates { + latitude: Latitude(-37.0321), + longitude: Longitude(175.122), + }; + + let calcs = SolarCalculations::new(date, coords); + assert_eq!(calcs.solar_noon_fraction, 0.4764071517220478); + } + + #[test] + fn test_midday_calcs_large_neg_offset() { + let date = FixedOffset::west((3600.0 * 9.5) as i32) + .ymd(2022, 7, 29) + .and_hms(12, 0, 0); + let coords = Coordinates { + latitude: Latitude(-9.3968), + longitude: Longitude(-140.0777), + }; + + let calcs = SolarCalculations::new(date, coords); + assert_eq!(calcs.solar_noon_fraction, 0.4977758080863915); + } + #[test] fn test_day_fraction_to_time_underoverflow() { // when a location is selected which is in a different time zone, it is possible for the sunrise/sunset to diff --git a/src/report.rs b/src/report.rs index eef5549..98b268d 100644 --- a/src/report.rs +++ b/src/report.rs @@ -236,15 +236,15 @@ mod tests { assert_eq!("04:26:26", report.sunrise.time().unwrap().to_string()); assert_eq!("22:02:52", report.sunset.time().unwrap().to_string()); assert_eq!("13:14:39", report.solar_noon.time().unwrap().to_string()); - assert_eq!("03:23:58", report.civil_dawn.time().unwrap().to_string()); - assert_eq!("23:05:21", report.civil_dusk.time().unwrap().to_string()); - assert_eq!(None, report.nautical_dawn.datetime); + assert_eq!("03:23:57", report.civil_dawn.time().unwrap().to_string()); + assert_eq!("23:05:20", report.civil_dusk.time().unwrap().to_string()); + assert_eq!(None, report.nautical_dawn.0); assert_eq!("Never".to_string(), format!("{}", report.nautical_dawn)); - assert_eq!(None, report.nautical_dusk.datetime); + assert_eq!(None, report.nautical_dusk.0); assert_eq!("Never".to_string(), format!("{}", report.nautical_dusk)); - assert_eq!(None, report.astronomical_dawn.datetime); + assert_eq!(None, report.astronomical_dawn.0); assert_eq!("Never".to_string(), format!("{}", report.astronomical_dawn)); - assert_eq!(None, report.astronomical_dusk.datetime); + assert_eq!(None, report.astronomical_dusk.0); assert_eq!("Never".to_string(), format!("{}", report.astronomical_dusk)); // now try with a non-zero time zone @@ -255,15 +255,15 @@ mod tests { let calcs = calc::SolarCalculations::new(date, coordinates); let report = SolarReport::new(calcs); - assert_eq!("06:46:57", report.sunrise.time().unwrap().to_string()); - assert_eq!("19:47:09", report.sunset.time().unwrap().to_string()); + assert_eq!("06:47:03", report.sunrise.time().unwrap().to_string()); + assert_eq!("19:47:03", report.sunset.time().unwrap().to_string()); assert_eq!("13:17:03", report.solar_noon.time().unwrap().to_string()); - assert_eq!("06:09:06", report.civil_dawn.time().unwrap().to_string()); - assert_eq!("20:24:59", report.civil_dusk.time().unwrap().to_string()); - assert_eq!("05:23:02", report.nautical_dawn.time().unwrap().to_string()); - assert_eq!("21:11:03", report.nautical_dusk.time().unwrap().to_string()); - assert_eq!("04:32:22", report.astronomical_dawn.time().unwrap().to_string()); - assert_eq!("22:01:43", report.astronomical_dusk.time().unwrap().to_string()); + assert_eq!("06:09:13", report.civil_dawn.time().unwrap().to_string()); + assert_eq!("20:24:53", report.civil_dusk.time().unwrap().to_string()); + assert_eq!("05:23:09", report.nautical_dawn.time().unwrap().to_string()); + assert_eq!("21:10:57", report.nautical_dusk.time().unwrap().to_string()); + assert_eq!("04:32:31", report.astronomical_dawn.time().unwrap().to_string()); + assert_eq!("22:01:36", report.astronomical_dusk.time().unwrap().to_string()); // at an extreme longitude with a very non-local timezone let date = DateTime::parse_from_rfc3339("2020-03-25T12:00:00+00:00").unwrap(); @@ -272,15 +272,15 @@ mod tests { let calcs = calc::SolarCalculations::new(date, coordinates); let report = SolarReport::new(calcs); - assert_eq!("2020-03-25 17:23:21 +00:00", report.sunrise.datetime.unwrap().to_string()); - assert_eq!("2020-03-26 06:00:14 +00:00", report.sunset.datetime.unwrap().to_string()); + assert_eq!("2020-03-25 17:23:21 +00:00", report.sunrise.0.unwrap().to_string()); + assert_eq!("2020-03-26 06:00:14 +00:00", report.sunset.0.unwrap().to_string()); assert_eq!("2020-03-25 23:41:48 +00:00", report.solar_noon.to_string()); - assert_eq!("2020-03-25 16:45:58 +00:00", report.civil_dawn.datetime.unwrap().to_string()); - assert_eq!("2020-03-26 06:37:37 +00:00", report.civil_dusk.datetime.unwrap().to_string()); - assert_eq!("2020-03-25 16:00:57 +00:00", report.nautical_dawn.datetime.unwrap().to_string()); - assert_eq!("2020-03-26 07:22:39 +00:00", report.nautical_dusk.datetime.unwrap().to_string()); - assert_eq!("2020-03-25 15:12:24 +00:00", report.astronomical_dawn.datetime.unwrap().to_string()); - assert_eq!("2020-03-26 08:11:12 +00:00", report.astronomical_dusk.datetime.unwrap().to_string()); + assert_eq!("2020-03-25 16:45:58 +00:00", report.civil_dawn.0.unwrap().to_string()); + assert_eq!("2020-03-26 06:37:37 +00:00", report.civil_dusk.0.unwrap().to_string()); + assert_eq!("2020-03-25 16:00:57 +00:00", report.nautical_dawn.0.unwrap().to_string()); + assert_eq!("2020-03-26 07:22:39 +00:00", report.nautical_dusk.0.unwrap().to_string()); + assert_eq!("2020-03-25 15:12:24 +00:00", report.astronomical_dawn.0.unwrap().to_string()); + assert_eq!("2020-03-26 08:11:12 +00:00", report.astronomical_dusk.0.unwrap().to_string()); // an extreme northern latitude during the summer let date = DateTime::parse_from_rfc3339("2020-06-21T12:00:00+02:00").unwrap(); @@ -289,15 +289,15 @@ mod tests { let calcs = calc::SolarCalculations::new(date, coordinates); let report = SolarReport::new(calcs); - assert_eq!(None, report.sunrise.datetime); - assert_eq!(None, report.sunset.datetime); - assert_eq!("12:59:22", report.solar_noon.time().unwrap().to_string()); - assert_eq!(None, report.civil_dawn.datetime); - assert_eq!(None, report.civil_dusk.datetime); - assert_eq!(None, report.nautical_dawn.datetime); - assert_eq!(None, report.nautical_dusk.datetime); - assert_eq!(None, report.astronomical_dawn.datetime); - assert_eq!(None, report.astronomical_dusk.datetime); + assert_eq!(None, report.sunrise.0); + assert_eq!(None, report.sunset.0); + assert_eq!("12:59:21", report.solar_noon.time().unwrap().to_string()); + assert_eq!(None, report.civil_dawn.0); + assert_eq!(None, report.civil_dusk.0); + assert_eq!(None, report.nautical_dawn.0); + assert_eq!(None, report.nautical_dusk.0); + assert_eq!(None, report.astronomical_dawn.0); + assert_eq!(None, report.astronomical_dusk.0); assert_eq!("24h 0m 0s", SolarReport::day_length_hms(report.day_length)); } @@ -337,12 +337,12 @@ mod tests { let expected = serde_json::json!({ "location": {"latitude": 51.4000, "longitude": -5.4670}, "date": "2022-06-11T12:00:00+01:00", - "day_length": 59537, - "solar_noon": "2022-06-11T13:21:32+01:00", - "sunrise": "2022-06-11T05:05:23+01:00", - "sunset": "2022-06-11T21:37:40+01:00", - "dawn": {"civil": "2022-06-11T04:18:28+01:00", "nautical": "2022-06-11T03:06:38+01:00", "astronomical": null}, - "dusk": {"civil": "2022-06-11T22:24:36+01:00", "nautical": "2022-06-11T23:36:26+01:00", "astronomical": null}, + "day_length": 59534, + "solar_noon": "2022-06-11T13:21:31+01:00", + "sunrise": "2022-06-11T05:05:24+01:00", + "sunset": "2022-06-11T21:37:38+01:00", + "dawn": {"civil": "2022-06-11T04:18:29+01:00", "nautical": "2022-06-11T03:06:40+01:00", "astronomical": null}, + "dusk": {"civil": "2022-06-11T22:24:34+01:00", "nautical": "2022-06-11T23:36:23+01:00", "astronomical": null}, }); assert_eq!(serde_json::to_value(report).unwrap(), expected); diff --git a/src/structs.rs b/src/structs.rs index b1a4ed3..d1c07d0 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -7,22 +7,22 @@ use super::errors::{ConfigErrorKind, HeliocronError}; type Result = result::Result; +/// A newtype representing an optional datetime. This allows us to provide custom +/// serialization methods when converting to a String or JSON. #[derive(Debug)] -pub struct EventTime { - pub datetime: Option>, -} +pub struct EventTime(pub Option>); impl EventTime { - pub fn new(datetime: Option>) -> EventTime { - EventTime { datetime } + pub fn new(datetime: Option>) -> Self { + Self(datetime) } pub fn is_some(&self) -> bool { - self.datetime.is_some() + self.0.is_some() } pub fn time(&self) -> Option { - self.datetime.map(|dt| dt.time()) + self.0.map(|dt| dt.time()) } } @@ -31,7 +31,7 @@ impl Serialize for EventTime { where S: serde::Serializer, { - match self.datetime { + match self.0 { Some(datetime) => serializer.serialize_str(&datetime.to_rfc3339()), None => serializer.serialize_none(), } @@ -43,7 +43,7 @@ impl fmt::Display for EventTime { write!( f, "{}", - match self.datetime { + match self.0 { Some(datetime) => datetime.to_string(), None => "Never".to_string(), } @@ -51,12 +51,6 @@ impl fmt::Display for EventTime { } } -impl From>> for EventTime { - fn from(datetime: Option>) -> EventTime { - EventTime::new(datetime) - } -} - fn invalid_coordinates_error(msg: &'static str) -> HeliocronError { HeliocronError::Config(ConfigErrorKind::InvalidCoordindates(msg)) } diff --git a/src/subcommands.rs b/src/subcommands.rs index 11f6ad8..f719001 100644 --- a/src/subcommands.rs +++ b/src/subcommands.rs @@ -28,7 +28,7 @@ pub async fn wait( _ => solar_calculations.calculate_event_time(event), }; - match event_time.datetime { + match event_time.0 { Some(datetime) => { let wait_until = datetime + offset; utils::wait(wait_until).await?; @@ -38,7 +38,6 @@ pub async fn wait( // if the event was missed. We allow a default tolerance of 30s, which should be more than enough to // catch any scheduling delays that could cause a second or two's delay. At some point, this arbitrary // number could be made configurable, if desired. - if run_missed_task { Ok(()) } else { diff --git a/tests/test_report.rs b/tests/test_report.rs index c3daac6..c3c593a 100644 --- a/tests/test_report.rs +++ b/tests/test_report.rs @@ -68,42 +68,115 @@ fn test_report_json_output() { let mut cmd = Command::cargo_bin("heliocron").unwrap(); // parse the output into a Json Value - let json_output: serde_json::Value = serde_json::from_str( - &String::from_utf8( - cmd.args(&[ - "--date", - "2022-06-11", - "--time-zone", - "+01:00", - "--latitude", - "51.4N", - "--longitude", - "5.4670W", - "report", - "--json", - ]) - .assert() - .success() - .get_output() - .stdout - .clone(), - ) - .unwrap(), + let json: serde_json::Value = serde_json::from_slice( + &cmd.args(&[ + "--date", + "2022-06-11", + "--time-zone", + "+01:00", + "--latitude", + "51.4N", + "--longitude", + "5.4670W", + "report", + "--json", + ]) + .assert() + .success() + .get_output() + .stdout + .clone(), ) .unwrap(); let expected = serde_json::json!({ "location": {"latitude": 51.4000, "longitude": -5.4670}, "date": "2022-06-11T12:00:00+01:00", - "day_length": 59537, - "solar_noon": "2022-06-11T13:21:32+01:00", - "sunrise": "2022-06-11T05:05:23+01:00", - "sunset": "2022-06-11T21:37:40+01:00", - "dawn": {"civil": "2022-06-11T04:18:28+01:00", "nautical": "2022-06-11T03:06:38+01:00", "astronomical": null}, - "dusk": {"civil": "2022-06-11T22:24:36+01:00", "nautical": "2022-06-11T23:36:26+01:00", "astronomical": null}, + "day_length": 59534, + "solar_noon": "2022-06-11T13:21:31+01:00", + "sunrise": "2022-06-11T05:05:24+01:00", + "sunset": "2022-06-11T21:37:38+01:00", + "dawn": {"civil": "2022-06-11T04:18:29+01:00", "nautical": "2022-06-11T03:06:40+01:00", "astronomical": null}, + "dusk": {"civil": "2022-06-11T22:24:34+01:00", "nautical": "2022-06-11T23:36:23+01:00", "astronomical": null}, + }); + + assert_eq!(json, expected); +} + +#[test] +fn test_correct_output() { + let output = Command::cargo_bin("heliocron") + .unwrap() + .args(&[ + "--date", + "2022-07-29", + "--time-zone", + "+01:00", + "--latitude", + "56.8197N", + "--longitude", + "5.1047W", + "report", + "--json", + ]) + .assert() + .success() + .get_output() + .stdout + .clone(); + + let json: serde_json::Value = serde_json::from_slice(&output).unwrap(); + + let expected = serde_json::json!({ + "location": {"latitude": 56.8197, "longitude": -5.1047}, + "date": "2022-07-29T12:00:00+01:00", + "day_length": 59066, + "solar_noon": "2022-07-29T13:26:55+01:00", + "sunrise": "2022-07-29T05:14:42+01:00", + "sunset": "2022-07-29T21:39:08+01:00", + "dawn": {"civil": "2022-07-29T04:23:01+01:00", "nautical": "2022-07-29T03:00:07+01:00", "astronomical": null}, + "dusk": {"civil": "2022-07-29T22:30:48+01:00", "nautical": "2022-07-29T23:53:43+01:00", "astronomical": null}, + }); + + assert_eq!(json, expected); +} + +#[test] +fn test_correct_output_nz() { + let output = Command::cargo_bin("heliocron") + .unwrap() + .args(&[ + "--date", + "2022-07-29", + "--time-zone", + "+11:00", + "--latitude", + "37.0321S", + "--longitude", + "175.1220E", + "report", + "--json", + ]) + .assert() + .success() + .get_output() + .stdout + .clone(); + + let json: serde_json::Value = serde_json::from_slice(&output).unwrap(); + + let expected = serde_json::json!({ + "location": {"latitude": -37.0321, "longitude": 175.122}, + "date": "2022-07-29T12:00:00+11:00", + "day_length": 36606, + "solar_noon": "2022-07-29T11:26:01+11:00", + "sunrise": "2022-07-29T06:20:58+11:00", + "sunset": "2022-07-29T16:31:04+11:00", + "dawn": {"civil": "2022-07-29T05:53:13+11:00", "nautical": "2022-07-29T05:21:48+11:00", "astronomical": "2022-07-29T04:51:00+11:00"}, + "dusk": {"civil": "2022-07-29T16:58:49+11:00", "nautical": "2022-07-29T17:30:14+11:00", "astronomical": "2022-07-29T18:01:02+11:00"}, }); - assert_eq!(json_output, expected); + assert_eq!(json, expected); } fn assert_report(report: Assert) { From bed9ca88e9f4a4e1ca12280eb65456bf7cb9f3a4 Mon Sep 17 00:00:00 2001 From: Michael Freeborn Date: Fri, 29 Jul 2022 17:25:44 +0100 Subject: [PATCH 2/4] clippy --- src/calc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calc.rs b/src/calc.rs index 9d785b5..6802306 100644 --- a/src/calc.rs +++ b/src/calc.rs @@ -1,4 +1,4 @@ -use chrono::{DateTime, Duration, FixedOffset, NaiveDateTime, NaiveTime, TimeZone, Timelike, Utc}; +use chrono::{DateTime, Duration, FixedOffset, NaiveTime, TimeZone}; use super::traits::{DateTimeExt, NaiveTimeExt}; use super::{enums, structs}; From 8fa9cd71e6bdc2c250f3542aa02042095e0324f1 Mon Sep 17 00:00:00 2001 From: Michael Freeborn Date: Sat, 30 Jul 2022 07:16:26 +0100 Subject: [PATCH 3/4] update deps --- Cargo.lock | 107 +++++++++++++++++++++++++---------------------------- 1 file changed, 51 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cd2617d..39d18a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,9 +59,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bytes" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e" [[package]] name = "cc" @@ -96,16 +96,16 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.18" +version = "3.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" +checksum = "a3dbbb6653e7c55cc8595ad3e1f7be8f32aba4eb7ff7f0fd1163d4f3d137c0a9" dependencies = [ "atty", "bitflags", "clap_derive", "clap_lex", "indexmap", - "lazy_static", + "once_cell", "strsim", "termcolor", "textwrap", @@ -113,9 +113,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.1.18" +version = "3.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" +checksum = "9ba52acd3b0a5c33aeada5cdaa3267cdc7c594a98731d4268cdc1532f4264cb4" dependencies = [ "heck", "proc-macro-error", @@ -126,18 +126,18 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.0" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" dependencies = [ "os_str_bytes", ] [[package]] name = "ctor" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" +checksum = "cdffe87e1d521a10f9696f833fe502293ea446d7f256c06128293a4119bdf4cb" dependencies = [ "quote", "syn", @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "diff" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] name = "difference" @@ -226,20 +226,20 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.10.0+wasi-snapshot-preview1", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" @@ -275,9 +275,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.8.2" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", "hashbrown", @@ -289,12 +289,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.126" @@ -328,9 +322,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mio" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" dependencies = [ "libc", "log", @@ -375,15 +369,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" [[package]] name = "os_str_bytes" -version = "6.1.0" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" +checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" [[package]] name = "output_vt100" @@ -490,27 +484,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.39" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" +checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] @@ -528,9 +522,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.6" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ "aho-corasick", "memchr", @@ -539,9 +533,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.26" +version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "ryu" @@ -557,18 +551,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.137" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da" dependencies = [ "proc-macro2", "quote", @@ -577,9 +571,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" dependencies = [ "itoa", "ryu", @@ -597,9 +591,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "socket2" @@ -619,9 +613,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.96" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" dependencies = [ "proc-macro2", "quote", @@ -682,10 +676,11 @@ dependencies = [ [[package]] name = "tokio" -version = "1.19.1" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95eec79ea28c00a365f539f1961e9278fbcaf81c0ff6aaf0e93c181352446948" +checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" dependencies = [ + "autocfg", "bytes", "libc", "memchr", @@ -735,9 +730,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" +checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" [[package]] name = "version_check" From 70a1914caabc8f0e7e8e4265719052ec176a372c Mon Sep 17 00:00:00 2001 From: Michael Freeborn Date: Sat, 30 Jul 2022 07:27:32 +0100 Subject: [PATCH 4/4] update deps --- Cargo.lock | 90 +++++++++++++++++++++++++++++++++--------------------- Cargo.toml | 14 ++++----- 2 files changed, 62 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 39d18a8..6914a4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,12 +22,12 @@ dependencies = [ [[package]] name = "assert_cmd" -version = "0.12.2" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936fcf2c692b37c696cd0002c57752b2d9478402450c9ca4a463f6afae16d6f5" +checksum = "93ae1ddd39efd67689deb1979d80bad3bf7f2b09c6e6117c8d1f2443b5e2f83e" dependencies = [ + "bstr", "doc-comment", - "escargot", "predicates", "predicates-core", "predicates-tree", @@ -57,6 +57,17 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata", +] + [[package]] name = "bytes" version = "1.2.0" @@ -69,12 +80,6 @@ version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -150,18 +155,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] -name = "difference" -version = "2.0.0" +name = "difflib" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" [[package]] name = "dirs" -version = "2.0.2" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" dependencies = [ - "cfg-if 0.1.10", "dirs-sys", ] @@ -182,6 +186,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "either" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" + [[package]] name = "errno" version = "0.2.8" @@ -203,23 +213,11 @@ dependencies = [ "libc", ] -[[package]] -name = "escargot" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5584ba17d7ab26a8a7284f13e5bd196294dd2f2d79773cff29b9e9edef601a6" -dependencies = [ - "log", - "once_cell", - "serde", - "serde_json", -] - [[package]] name = "float-cmp" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" dependencies = [ "num-traits", ] @@ -230,7 +228,7 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi 0.11.0+wasi-snapshot-preview1", ] @@ -283,12 +281,27 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.126" @@ -311,7 +324,7 @@ version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -404,7 +417,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "redox_syscall", "smallvec", @@ -419,12 +432,13 @@ checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "predicates" -version = "1.0.8" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49cfaf7fdaa3bfacc6fa3e7054e65148878354a5cfddcf661df4c851f8021df" +checksum = "a5aab5be6e4732b473071984b3164dbbfb7a3674d30ea5ff44410b6bcd960c3c" dependencies = [ - "difference", + "difflib", "float-cmp", + "itertools", "normalize-line-endings", "predicates-core", "regex", @@ -531,6 +545,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" + [[package]] name = "regex-syntax" version = "0.6.27" diff --git a/Cargo.toml b/Cargo.toml index 07a8ea2..dd9d025 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,18 +23,18 @@ integration-test = [] [dependencies] chrono = "0.4" -dirs = "2.0" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -clap = { version = "3.1", features = ["derive"] } +dirs = "4" +serde = { version = "1", features = ["derive"] } +serde_json = "1" +clap = { version = "3", features = ["derive"] } tokio = { version = "1", features = ["full"] } tokio-walltime = "0.1.2" toml = "0.5" [dev-dependencies] -assert_cmd = "0.12" -predicates = "1" -pretty_assertions = "1.2.1" +assert_cmd = "2" +predicates = "2" +pretty_assertions = "1" [profile.release] codegen-units = 1