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(
unix_seconds: i64,
subsec_millis: u32,
unix_stamp: &UnixTimestamp,
days_len: LengthOfDaySegment,
) -> 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)
}
@ -763,10 +765,9 @@ impl TimeProvider<DaysLen24Bits> {
/// [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, 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.
@ -849,10 +850,9 @@ impl TimeProvider<DaysLen16Bits> {
/// [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, 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.
@ -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::<Utc>::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")
}

View File

@ -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<Self> {
pub fn new(unix_seconds: i64, subsec_millis: u16) -> Option<Self> {
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<u16> {
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"))]
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();