Time module extensions #9

Merged
muellerr merged 34 commits from time_extensions into main 2023-01-16 17:51:28 +01:00
4 changed files with 27 additions and 19 deletions
Showing only changes of commit 6f795690fd - Show all commits

View File

@ -13,6 +13,22 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- CDS timestamp: Added constructor function to create the time provider - CDS timestamp: Added constructor function to create the time provider
from `chrono::DateTime<Utc>` and a generic UNIX timestamp (`i64` seconds from `chrono::DateTime<Utc>` and a generic UNIX timestamp (`i64` seconds
and subsecond milliseconds). and subsecond milliseconds).
- New `UnixTimeStamp` abstraction which contains the unix seconds as an `i64`
and an optional subsecond millisecond counter (`u16`)
- `MAX_DAYS_24_BITS` which contains maximum value which can be supplied
to the days field of a CDS time provider with 24 bits days field width.
## Changed
- `CcsdsTimeProvider` trait (breaking):
- Add new `unix_stamp` method returning the new `UnixTimeStamp` struct
- Add new `subsecond_millis` method returning counter `Option<u16>`
- Default impl for `unix_stamp` which re-uses `subsecond_millis` and
existing `unix_seconds` method
- `TimestampError` (breaking): Add `DateBeforeCcsdsEpoch` error type
because new CDS API allow supplying invalid date times before CCSDS epoch.
Make `TimestampError` with `#[non_exhaustive]` attribute to prevent
future breakages if new error variants are added
# [v0.4.2] 14.01.2023 # [v0.4.2] 14.01.2023

View File

@ -167,7 +167,7 @@ pub struct TimeProvider<DaysLen: ProvidesDaysLength = DaysLen16Bits> {
submillis_precision: Option<SubmillisPrecision>, submillis_precision: Option<SubmillisPrecision>,
/// This is not strictly necessary but still cached because it significantly simplifies the /// This is not strictly necessary but still cached because it significantly simplifies the
/// calculation of [`DateTime<Utc>`]. /// calculation of [`DateTime<Utc>`].
unix_stamp: UnixTimeStamp, unix_stamp: UnixTimestamp,
} }
/// Common properties for all CDS time providers. /// Common properties for all CDS time providers.
@ -1096,7 +1096,7 @@ impl<ProvidesDaysLen: ProvidesDaysLength> CcsdsTimeProvider for TimeProvider<Pro
} }
#[inline] #[inline]
fn unix_stamp(&self) -> UnixTimeStamp { fn unix_stamp(&self) -> UnixTimestamp {
self.unix_stamp self.unix_stamp
} }

View File

@ -565,15 +565,6 @@ impl CcsdsTimeProvider for TimeProviderCcsdsEpoch {
None None
} }
/// Please note that this function only works as intended if the time counter resolution
/// is one second.
fn unix_stamp(&self) -> UnixTimeStamp {
UnixTimeStamp {
unix_seconds: self.unix_seconds(),
subsecond_millis: None,
}
}
fn date_time(&self) -> Option<DateTime<Utc>> { fn date_time(&self) -> Option<DateTime<Utc>> {
let unix_seconds = self.unix_seconds(); let unix_seconds = self.unix_seconds();
let ns = if let Some(fractional_part) = self.fractions { let ns = if let Some(fractional_part) = self.fractions {

View File

@ -56,6 +56,7 @@ pub fn ccsds_time_code_from_p_field(pfield: u8) -> Result<CcsdsTimeCodes, u8> {
#[derive(Debug, PartialEq, Eq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[non_exhaustive]
pub enum TimestampError { pub enum TimestampError {
/// Contains tuple where first value is the expected time code and the second /// Contains tuple where first value is the expected time code and the second
/// value is the found raw value /// value is the found raw value
@ -219,8 +220,8 @@ pub trait CcsdsTimeProvider {
fn unix_seconds(&self) -> i64; fn unix_seconds(&self) -> i64;
fn subsecond_millis(&self) -> Option<u16>; fn subsecond_millis(&self) -> Option<u16>;
fn unix_stamp(&self) -> UnixTimeStamp { fn unix_stamp(&self) -> UnixTimestamp {
UnixTimeStamp { UnixTimestamp {
unix_seconds: self.unix_seconds(), unix_seconds: self.unix_seconds(),
subsecond_millis: self.subsecond_millis(), subsecond_millis: self.subsecond_millis(),
} }
@ -234,12 +235,12 @@ pub trait CcsdsTimeProvider {
/// Also can optionally include subsecond millisecond for greater accuracy. /// Also can optionally include subsecond millisecond for greater accuracy.
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)] #[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct UnixTimeStamp { pub struct UnixTimestamp {
pub unix_seconds: i64, pub unix_seconds: i64,
subsecond_millis: Option<u16>, subsecond_millis: Option<u16>,
} }
impl UnixTimeStamp { impl UnixTimestamp {
pub fn new(unix_seconds: i64) -> Self { pub fn new(unix_seconds: i64) -> Self {
Self { Self {
unix_seconds, unix_seconds,
@ -267,7 +268,7 @@ impl UnixTimeStamp {
pub fn from_now() -> Result<Self, SystemTimeError> { pub fn from_now() -> Result<Self, SystemTimeError> {
let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?; let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?;
let epoch = now.as_secs(); let epoch = now.as_secs();
Ok(UnixTimeStamp { Ok(UnixTimestamp {
unix_seconds: epoch as i64, unix_seconds: epoch as i64,
subsecond_millis: Some(now.subsec_millis() as u16), subsecond_millis: Some(now.subsec_millis() as u16),
}) })
@ -314,17 +315,17 @@ mod tests {
#[test] #[test]
fn basic_unix_stamp_test() { fn basic_unix_stamp_test() {
let stamp = UnixTimeStamp::new(-200); let stamp = UnixTimestamp::new(-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(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_with_subsecond_millis(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();