use new struct in API

This commit is contained in:
Robin Müller 2023-01-15 21:30:31 +01:00
parent 2f51420a29
commit 708b68a5cb
No known key found for this signature in database
GPG Key ID: BE6480244DFE612C
2 changed files with 64 additions and 31 deletions

View File

@ -638,11 +638,13 @@ impl<ProvidesDaysLen: ProvidesDaysLength> TimeProvider<ProvidesDaysLen> {
} }
fn from_unix_generic( fn from_unix_generic(
unix_seconds: i64, unix_stamp: &UnixTimestamp,
subsec_millis: u32,
days_len: LengthOfDaySegment, days_len: LengthOfDaySegment,
) -> Result<Self, TimestampError> { ) -> Result<Self, TimestampError> {
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) Self::generic_from_conversion(days_len, conv_from_dt)
} }
@ -763,10 +765,9 @@ impl TimeProvider<DaysLen24Bits> {
/// [TimestampError::CdsError] if the time is before the CCSDS epoch (01-01-1958 00:00:00) or /// [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). /// the CCSDS days value exceeds the allowed bit width (24 bits).
pub fn from_unix_secs_with_u24_days( pub fn from_unix_secs_with_u24_days(
unix_seconds: i64, unix_stamp: &UnixTimestamp,
subsec_millis: u32,
) -> Result<Self, TimestampError> { ) -> Result<Self, TimestampError> {
Self::from_unix_generic(unix_seconds, subsec_millis, LengthOfDaySegment::Long24Bits) Self::from_unix_generic(unix_stamp, LengthOfDaySegment::Long24Bits)
} }
/// Create a provider from a [`DateTime<Utc>`] struct. /// Create a provider from a [`DateTime<Utc>`] struct.
@ -849,10 +850,9 @@ impl TimeProvider<DaysLen16Bits> {
/// [TimestampError::CdsError] if the time is before the CCSDS epoch (01-01-1958 00:00:00) or /// [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). /// the CCSDS days value exceeds the allowed bit width (24 bits).
pub fn from_unix_secs_with_u16_days( pub fn from_unix_secs_with_u16_days(
unix_seconds: i64, unix_stamp: &UnixTimestamp,
subsec_millis: u32,
) -> Result<Self, TimestampError> { ) -> Result<Self, TimestampError> {
Self::from_unix_generic(unix_seconds, subsec_millis, LengthOfDaySegment::Short16Bits) Self::from_unix_generic(unix_stamp, LengthOfDaySegment::Short16Bits)
} }
/// Create a provider from a [`DateTime<Utc>`] struct. /// Create a provider from a [`DateTime<Utc>`] struct.
@ -1754,8 +1754,11 @@ mod tests {
fn test_creation_from_unix_stamp_0_u16_days() { fn test_creation_from_unix_stamp_0_u16_days() {
let unix_secs = 0; let unix_secs = 0;
let subsec_millis = 0; let subsec_millis = 0;
let time_provider = TimeProvider::from_unix_secs_with_u16_days(unix_secs, subsec_millis) let time_provider = TimeProvider::from_unix_secs_with_u16_days(&UnixTimestamp::const_new(
.expect("creating provider from unix stamp failed"); unix_secs,
subsec_millis,
))
.expect("creating provider from unix stamp failed");
assert_eq!(time_provider.ccsds_days, -DAYS_CCSDS_TO_UNIX as u16) 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() { fn test_creation_from_unix_stamp_0_u24_days() {
let unix_secs = 0; let unix_secs = 0;
let subsec_millis = 0; let subsec_millis = 0;
let time_provider = TimeProvider::from_unix_secs_with_u24_days(unix_secs, subsec_millis) let time_provider = TimeProvider::from_unix_secs_with_u24_days(&UnixTimestamp::const_new(
.expect("creating provider from unix stamp failed"); unix_secs,
subsec_millis,
))
.expect("creating provider from unix stamp failed");
assert_eq!(time_provider.ccsds_days, (-DAYS_CCSDS_TO_UNIX) as u32) 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) .and_hms_milli_opt(16, 49, 30, subsec_millis)
.unwrap(); .unwrap();
let datetime_utc = DateTime::<Utc>::from_utc(naivedatetime_utc, Utc); let datetime_utc = DateTime::<Utc>::from_utc(naivedatetime_utc, Utc);
let time_provider = let time_provider = TimeProvider::from_unix_secs_with_u16_days(&datetime_utc.into())
TimeProvider::from_unix_secs_with_u16_days(datetime_utc.timestamp(), subsec_millis) .expect("creating provider from unix stamp failed");
.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 // 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. // Leap years need to be accounted for as well.
assert_eq!(time_provider.ccsds_days, 23754); assert_eq!(time_provider.ccsds_days, 23754);
@ -1794,8 +1799,11 @@ mod tests {
fn test_creation_0_ccsds_days() { fn test_creation_0_ccsds_days() {
let unix_secs = DAYS_CCSDS_TO_UNIX as i64 * SECONDS_PER_DAY as i64; let unix_secs = DAYS_CCSDS_TO_UNIX as i64 * SECONDS_PER_DAY as i64;
let subsec_millis = 0; let subsec_millis = 0;
let time_provider = TimeProvider::from_unix_secs_with_u16_days(unix_secs, subsec_millis) let time_provider = TimeProvider::from_unix_secs_with_u16_days(&UnixTimestamp::const_new(
.expect("creating provider from unix stamp failed"); unix_secs,
subsec_millis,
))
.expect("creating provider from unix stamp failed");
assert_eq!(time_provider.ccsds_days, 0) assert_eq!(time_provider.ccsds_days, 0)
} }
@ -1803,7 +1811,10 @@ mod tests {
fn test_invalid_creation_from_unix_stamp_days_too_large() { 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 invalid_unix_secs: i64 = (u16::MAX as i64 + 1) * SECONDS_PER_DAY as i64;
let subsec_millis = 0; 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(_) => { Ok(_) => {
panic!("creation should not succeed") panic!("creation should not succeed")
} }
@ -1826,7 +1837,10 @@ mod tests {
// precisely 31-12-1957 23:59:55 // precisely 31-12-1957 23:59:55
let unix_secs = DAYS_CCSDS_TO_UNIX * SECONDS_PER_DAY as i32 - 5; let unix_secs = DAYS_CCSDS_TO_UNIX * SECONDS_PER_DAY as i32 - 5;
let subsec_millis = 0; 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(_) => { Ok(_) => {
panic!("creation should not succeed") panic!("creation should not succeed")
} }

View File

@ -241,15 +241,8 @@ pub struct UnixTimestamp {
} }
impl 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. /// Returns none if the subsecond millisecond value is larger than 999.
pub fn new_with_subsecond_millis(unix_seconds: i64, subsec_millis: u16) -> Option<Self> { pub fn new(unix_seconds: i64, subsec_millis: u16) -> Option<Self> {
if subsec_millis > 999 { if subsec_millis > 999 {
return None; 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<u16> { pub fn subsecond_millis(&self) -> Option<u16> {
self.subsecond_millis self.subsecond_millis
} }
@ -284,6 +294,15 @@ impl UnixTimestamp {
} }
} }
impl From<DateTime<Utc>> for UnixTimestamp {
fn from(value: DateTime<Utc>) -> Self {
Self {
unix_seconds: value.timestamp(),
subsecond_millis: Some(value.timestamp_subsec_millis() as u16),
}
}
}
#[cfg(all(test, feature = "std"))] #[cfg(all(test, feature = "std"))]
mod tests { mod tests {
use super::*; use super::*;
@ -315,17 +334,17 @@ mod tests {
#[test] #[test]
fn basic_unix_stamp_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_eq!(stamp.unix_seconds, -200);
assert!(stamp.subsecond_millis().is_none()); 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_eq!(stamp.unix_seconds, 250);
assert!(stamp.subsecond_millis().is_none()); assert!(stamp.subsecond_millis().is_none());
} }
#[test] #[test]
fn basic_float_unix_stamp_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!(stamp.subsecond_millis.is_some());
assert_eq!(stamp.unix_seconds, 500); assert_eq!(stamp.unix_seconds, 500);
let subsec_millis = stamp.subsecond_millis().unwrap(); let subsec_millis = stamp.subsecond_millis().unwrap();