From 708b68a5cbc243caa4eaf0687563ec8be7900086 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 15 Jan 2023 21:30:31 +0100 Subject: [PATCH] use new struct in API --- src/time/cds.rs | 54 +++++++++++++++++++++++++++++++------------------ src/time/mod.rs | 41 +++++++++++++++++++++++++++---------- 2 files changed, 64 insertions(+), 31 deletions(-) diff --git a/src/time/cds.rs b/src/time/cds.rs index bbf20ba..3c250eb 100644 --- a/src/time/cds.rs +++ b/src/time/cds.rs @@ -638,11 +638,13 @@ impl TimeProvider { } fn from_unix_generic( - unix_seconds: i64, - subsec_millis: u32, + unix_stamp: &UnixTimestamp, days_len: LengthOfDaySegment, ) -> Result { - let conv_from_dt = ConversionFromUnix::new(unix_seconds, subsec_millis)?; + let conv_from_dt = ConversionFromUnix::new( + unix_stamp.unix_seconds, + unix_stamp.subsecond_millis.unwrap_or(0) as u32, + )?; Self::generic_from_conversion(days_len, conv_from_dt) } @@ -763,10 +765,9 @@ impl TimeProvider { /// [TimestampError::CdsError] if the time is before the CCSDS epoch (01-01-1958 00:00:00) or /// the CCSDS days value exceeds the allowed bit width (24 bits). pub fn from_unix_secs_with_u24_days( - unix_seconds: i64, - subsec_millis: u32, + unix_stamp: &UnixTimestamp, ) -> Result { - Self::from_unix_generic(unix_seconds, subsec_millis, LengthOfDaySegment::Long24Bits) + Self::from_unix_generic(unix_stamp, LengthOfDaySegment::Long24Bits) } /// Create a provider from a [`DateTime`] struct. @@ -849,10 +850,9 @@ impl TimeProvider { /// [TimestampError::CdsError] if the time is before the CCSDS epoch (01-01-1958 00:00:00) or /// the CCSDS days value exceeds the allowed bit width (24 bits). pub fn from_unix_secs_with_u16_days( - unix_seconds: i64, - subsec_millis: u32, + unix_stamp: &UnixTimestamp, ) -> Result { - Self::from_unix_generic(unix_seconds, subsec_millis, LengthOfDaySegment::Short16Bits) + Self::from_unix_generic(unix_stamp, LengthOfDaySegment::Short16Bits) } /// Create a provider from a [`DateTime`] struct. @@ -1754,8 +1754,11 @@ mod tests { fn test_creation_from_unix_stamp_0_u16_days() { let unix_secs = 0; let subsec_millis = 0; - let time_provider = TimeProvider::from_unix_secs_with_u16_days(unix_secs, subsec_millis) - .expect("creating provider from unix stamp failed"); + let time_provider = TimeProvider::from_unix_secs_with_u16_days(&UnixTimestamp::const_new( + unix_secs, + subsec_millis, + )) + .expect("creating provider from unix stamp failed"); assert_eq!(time_provider.ccsds_days, -DAYS_CCSDS_TO_UNIX as u16) } @@ -1763,8 +1766,11 @@ mod tests { fn test_creation_from_unix_stamp_0_u24_days() { let unix_secs = 0; let subsec_millis = 0; - let time_provider = TimeProvider::from_unix_secs_with_u24_days(unix_secs, subsec_millis) - .expect("creating provider from unix stamp failed"); + let time_provider = TimeProvider::from_unix_secs_with_u24_days(&UnixTimestamp::const_new( + unix_secs, + subsec_millis, + )) + .expect("creating provider from unix stamp failed"); assert_eq!(time_provider.ccsds_days, (-DAYS_CCSDS_TO_UNIX) as u32) } @@ -1776,9 +1782,8 @@ mod tests { .and_hms_milli_opt(16, 49, 30, subsec_millis) .unwrap(); let datetime_utc = DateTime::::from_utc(naivedatetime_utc, Utc); - let time_provider = - TimeProvider::from_unix_secs_with_u16_days(datetime_utc.timestamp(), subsec_millis) - .expect("creating provider from unix stamp failed"); + let time_provider = TimeProvider::from_unix_secs_with_u16_days(&datetime_utc.into()) + .expect("creating provider from unix stamp failed"); // https://www.timeanddate.com/date/durationresult.html?d1=01&m1=01&y1=1958&d2=14&m2=01&y2=2023 // Leap years need to be accounted for as well. assert_eq!(time_provider.ccsds_days, 23754); @@ -1794,8 +1799,11 @@ mod tests { fn test_creation_0_ccsds_days() { let unix_secs = DAYS_CCSDS_TO_UNIX as i64 * SECONDS_PER_DAY as i64; let subsec_millis = 0; - let time_provider = TimeProvider::from_unix_secs_with_u16_days(unix_secs, subsec_millis) - .expect("creating provider from unix stamp failed"); + let time_provider = TimeProvider::from_unix_secs_with_u16_days(&UnixTimestamp::const_new( + unix_secs, + subsec_millis, + )) + .expect("creating provider from unix stamp failed"); assert_eq!(time_provider.ccsds_days, 0) } @@ -1803,7 +1811,10 @@ mod tests { fn test_invalid_creation_from_unix_stamp_days_too_large() { let invalid_unix_secs: i64 = (u16::MAX as i64 + 1) * SECONDS_PER_DAY as i64; let subsec_millis = 0; - match TimeProvider::from_unix_secs_with_u16_days(invalid_unix_secs as i64, subsec_millis) { + match TimeProvider::from_unix_secs_with_u16_days(&UnixTimestamp::const_new( + invalid_unix_secs as i64, + subsec_millis, + )) { Ok(_) => { panic!("creation should not succeed") } @@ -1826,7 +1837,10 @@ mod tests { // precisely 31-12-1957 23:59:55 let unix_secs = DAYS_CCSDS_TO_UNIX * SECONDS_PER_DAY as i32 - 5; let subsec_millis = 0; - match TimeProvider::from_unix_secs_with_u16_days(unix_secs as i64, subsec_millis) { + match TimeProvider::from_unix_secs_with_u16_days(&UnixTimestamp::const_new( + unix_secs as i64, + subsec_millis, + )) { Ok(_) => { panic!("creation should not succeed") } diff --git a/src/time/mod.rs b/src/time/mod.rs index 9af0cf5..2fadb96 100644 --- a/src/time/mod.rs +++ b/src/time/mod.rs @@ -241,15 +241,8 @@ pub struct UnixTimestamp { } impl UnixTimestamp { - pub fn new(unix_seconds: i64) -> Self { - Self { - unix_seconds, - subsecond_millis: None, - } - } - /// Returns none if the subsecond millisecond value is larger than 999. - pub fn new_with_subsecond_millis(unix_seconds: i64, subsec_millis: u16) -> Option { + pub fn new(unix_seconds: i64, subsec_millis: u16) -> Option { if subsec_millis > 999 { return None; } @@ -259,6 +252,23 @@ impl UnixTimestamp { }) } + pub const fn const_new(unix_seconds: i64, subsec_millis: u16) -> Self { + if subsec_millis > 999 { + panic!("subsec milliseconds exceeds 999"); + } + Self { + unix_seconds, + subsecond_millis: Some(subsec_millis), + } + } + + pub fn new_only_seconds(unix_seconds: i64) -> Self { + Self { + unix_seconds, + subsecond_millis: None, + } + } + pub fn subsecond_millis(&self) -> Option { self.subsecond_millis } @@ -284,6 +294,15 @@ impl UnixTimestamp { } } +impl From> for UnixTimestamp { + fn from(value: DateTime) -> Self { + Self { + unix_seconds: value.timestamp(), + subsecond_millis: Some(value.timestamp_subsec_millis() as u16), + } + } +} + #[cfg(all(test, feature = "std"))] mod tests { use super::*; @@ -315,17 +334,17 @@ mod tests { #[test] fn basic_unix_stamp_test() { - let stamp = UnixTimestamp::new(-200); + let stamp = UnixTimestamp::new_only_seconds(-200); assert_eq!(stamp.unix_seconds, -200); assert!(stamp.subsecond_millis().is_none()); - let stamp = UnixTimestamp::new(250); + let stamp = UnixTimestamp::new_only_seconds(250); assert_eq!(stamp.unix_seconds, 250); assert!(stamp.subsecond_millis().is_none()); } #[test] fn basic_float_unix_stamp_test() { - let stamp = UnixTimestamp::new_with_subsecond_millis(500, 600).unwrap(); + let stamp = UnixTimestamp::new(500, 600).unwrap(); assert!(stamp.subsecond_millis.is_some()); assert_eq!(stamp.unix_seconds, 500); let subsec_millis = stamp.subsecond_millis().unwrap();