diff --git a/CHANGELOG.md b/CHANGELOG.md index 59045df..cdf19c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ to check all the API changes in the **Changed** chapter. - `UnixTimestamp` renamed to `UnixTime` - `UnixTime` seconds are now private and can be retrieved using the `secs` member method. - `UnixTime::new` renamed to `UnixTime::new_checked`. +- `UnixTime::secs` renamed to `UnixTime::as_secs`. - `UnixTime` now has a nanosecond subsecond precision. The `new` constructor now expects nanoseconds as the second argument. - Added new `UnixTime::new_subsec_millis` and `UnixTime::new_subsec_millis_checked` API @@ -48,6 +49,7 @@ to check all the API changes in the **Changed** chapter. `CdsError` and `CucError`. - `PusTmCreator` now has two lifetimes: One for the raw source data buffer and one for the raw timestamp. +- Time API `from_now*` API renamed to `now*`. ## Removed diff --git a/src/ecss/tc.rs b/src/ecss/tc.rs index 93655cb..b5e4c1e 100644 --- a/src/ecss/tc.rs +++ b/src/ecss/tc.rs @@ -237,7 +237,7 @@ impl<'raw_data> PusTcCreator<'raw_data> { /// and subservice type /// * `app_data` - Custom application data /// * `set_ccsds_len` - Can be used to automatically update the CCSDS space packet data length - /// field. If this is not set to true, [PusTc::update_ccsds_data_len] can be called to set + /// field. If this is not set to true, [Self::update_ccsds_data_len] can be called to set /// the correct value to this field manually pub fn new( sp_header: &mut SpHeader, @@ -258,7 +258,7 @@ impl<'raw_data> PusTcCreator<'raw_data> { pus_tc } - /// Simplified version of the [PusTcCreator::new] function which allows to only specify service + /// Simplified version of the [Self::new] function which allows to only specify service /// and subservice instead of the full PUS TC secondary header. pub fn new_simple( sph: &mut SpHeader, @@ -302,7 +302,7 @@ impl<'raw_data> PusTcCreator<'raw_data> { sp_header_impls!(); /// Calculate the CCSDS space packet data length field and sets it - /// This is called automatically if the `set_ccsds_len` argument in the [PusTc::new] call was + /// This is called automatically if the `set_ccsds_len` argument in the [Self::new] call was /// used. /// If this was not done or the application data is set or changed after construction, /// this function needs to be called to ensure that the data length field of the CCSDS header @@ -312,8 +312,7 @@ impl<'raw_data> PusTcCreator<'raw_data> { self.len_written() as u16 - size_of::() as u16 - 1; } - /// This function should be called before the TC packet is serialized if - /// [PusTc::calc_crc_on_serialization] is set to False. It will calculate and cache the CRC16. + /// This function calculates and returns the CRC16 for the current packet. pub fn calc_own_crc16(&self) -> u16 { let mut digest = CRC_CCITT_FALSE.digest(); let sph_zc = crate::zc::SpHeader::from(self.sp_header); diff --git a/src/ecss/tm.rs b/src/ecss/tm.rs index 43388ee..88c3edd 100644 --- a/src/ecss/tm.rs +++ b/src/ecss/tm.rs @@ -212,10 +212,11 @@ impl<'slice> TryFrom> for PusTmSecondaryHeader<'slice #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct PusTmCreator<'time, 'raw_data> { pub sp_header: SpHeader, + #[cfg_attr(feature="serde", serde(borrow))] pub sec_header: PusTmSecondaryHeader<'time>, source_data: &'raw_data [u8], - /// If this is set to false, a manual call to [PusTm::calc_own_crc16] or - /// [PusTm::update_packet_fields] is necessary for the serialized or cached CRC16 to be valid. + /// If this is set to false, a manual call to [Self::calc_own_crc16] or + /// [Self::update_packet_fields] is necessary for the serialized or cached CRC16 to be valid. pub calc_crc_on_serialization: bool, } @@ -230,7 +231,7 @@ impl<'time, 'raw_data> PusTmCreator<'time, 'raw_data> { /// and subservice type /// * `source_data` - Custom application data /// * `set_ccsds_len` - Can be used to automatically update the CCSDS space packet data length - /// field. If this is not set to true, [PusTm::update_ccsds_data_len] can be called to set + /// field. If this is not set to true, [Self::update_ccsds_data_len] can be called to set /// the correct value to this field manually pub fn new( sp_header: &mut SpHeader, @@ -302,7 +303,7 @@ impl<'time, 'raw_data> PusTmCreator<'time, 'raw_data> { sp_header_impls!(); - /// This is called automatically if the `set_ccsds_len` argument in the [PusTm::new] call was + /// This is called automatically if the `set_ccsds_len` argument in the [Self::new] call was /// used. /// If this was not done or the time stamp or source data is set or changed after construction, /// this function needs to be called to ensure that the data length field of the CCSDS header @@ -313,7 +314,7 @@ impl<'time, 'raw_data> PusTmCreator<'time, 'raw_data> { } /// This function should be called before the TM packet is serialized if - /// [PusTm.calc_crc_on_serialization] is set to False. It will calculate and cache the CRC16. + /// [Self::calc_crc_on_serialization] is set to False. It will calculate and cache the CRC16. pub fn calc_own_crc16(&self) -> u16 { let mut digest = CRC_CCITT_FALSE.digest(); let sph_zc = crate::zc::SpHeader::from(self.sp_header); @@ -325,7 +326,7 @@ impl<'time, 'raw_data> PusTmCreator<'time, 'raw_data> { digest.finalize() } - /// This helper function calls both [PusTm.update_ccsds_data_len] and [PusTm.calc_own_crc16] + /// This helper function calls both [Self::update_ccsds_data_len] and [Self::calc_own_crc16] pub fn update_packet_fields(&mut self) { self.update_ccsds_data_len(); } diff --git a/src/time/cds.rs b/src/time/cds.rs index 5074b92..388437c 100644 --- a/src/time/cds.rs +++ b/src/time/cds.rs @@ -176,7 +176,7 @@ pub fn precision_from_pfield(pfield: u8) -> SubmillisPrecision { /// use spacepackets::time::cds::{CdsTime, length_of_day_segment_from_pfield, LengthOfDaySegment}; /// use spacepackets::time::{TimeWriter, CcsdsTimeCode, CcsdsTimeProvider}; /// -/// let timestamp_now = CdsTime::from_now_with_u16_days().unwrap(); +/// let timestamp_now = CdsTime::now_with_u16_days().unwrap(); /// let mut raw_stamp = [0; 7]; /// { /// let written = timestamp_now.write_to_bytes(&mut raw_stamp).unwrap(); @@ -727,14 +727,14 @@ impl CdsTime { } #[cfg(feature = "std")] - fn from_now_generic(days_len: LengthOfDaySegment) -> Result { + fn now_generic(days_len: LengthOfDaySegment) -> Result { let conversion_from_now = ConversionFromNow::new()?; Self::generic_from_conversion(days_len, conversion_from_now) .map_err(|e| StdTimestampError::Timestamp(TimestampError::from(e))) } #[cfg(feature = "std")] - fn from_now_generic_us_prec(days_len: LengthOfDaySegment) -> Result { + fn now_generic_with_us_prec(days_len: LengthOfDaySegment) -> Result { let conversion_from_now = ConversionFromNow::new_with_submillis_us_prec()?; Self::generic_from_conversion(days_len, conversion_from_now) .map_err(|e| StdTimestampError::Timestamp(TimestampError::from(e))) @@ -822,8 +822,8 @@ impl CdsTime { /// Generate a time stamp from the current time using the system clock. #[cfg(feature = "std")] - pub fn from_now_with_u24_days() -> Result { - Self::from_now_generic(LengthOfDaySegment::Long24Bits) + pub fn now_with_u24_days() -> Result { + Self::now_generic(LengthOfDaySegment::Long24Bits) } /// Create a provider from a [`chrono::DateTime`] struct. @@ -845,7 +845,7 @@ impl CdsTime { /// This function will return [CdsError::DateBeforeCcsdsEpoch] if the time is before the CCSDS /// epoch (1958-01-01T00:00:00+00:00) or the CCSDS days value exceeds the allowed bit width /// (24 bits). - pub fn from_unix_stamp_with_u24_days( + pub fn from_unix_time_with_u24_day( unix_stamp: &UnixTime, submillis_prec: SubmillisPrecision, ) -> Result { @@ -868,16 +868,16 @@ impl CdsTime { Self::from_dt_generic_ps_prec(dt, LengthOfDaySegment::Long24Bits) } - /// Like [Self::from_now_with_u24_days] but with microsecond sub-millisecond precision. + /// Like [Self::now_with_u24_days] but with microsecond sub-millisecond precision. #[cfg(feature = "std")] - pub fn from_now_with_u24_days_us_precision() -> Result { - Self::from_now_generic_us_prec(LengthOfDaySegment::Long24Bits) + pub fn now_with_u24_days_us_precision() -> Result { + Self::now_generic_with_us_prec(LengthOfDaySegment::Long24Bits) } - /// Like [Self::from_now_with_u24_days] but with picoseconds sub-millisecond precision. + /// Like [Self::now_with_u24_days] but with picoseconds sub-millisecond precision. #[cfg(feature = "std")] - pub fn from_now_with_u24_days_ps_precision() -> Result { - Self::from_now_generic_us_prec(LengthOfDaySegment::Long24Bits) + pub fn now_with_u24_days_ps_precision() -> Result { + Self::now_generic_with_us_prec(LengthOfDaySegment::Long24Bits) } pub fn from_bytes_with_u24_days(buf: &[u8]) -> Result { @@ -926,8 +926,8 @@ impl CdsTime { /// Generate a time stamp from the current time using the system clock. #[cfg(feature = "std")] - pub fn from_now_with_u16_days() -> Result { - Self::from_now_generic(LengthOfDaySegment::Short16Bits) + pub fn now_with_u16_days() -> Result { + Self::now_generic(LengthOfDaySegment::Short16Bits) } /// Create a provider from a generic UNIX timestamp (seconds since 1970-01-01T00:00:00+00:00). @@ -937,7 +937,7 @@ impl CdsTime { /// This function will return [CdsError::DateBeforeCcsdsEpoch] if the time is before the CCSDS /// epoch (1958-01-01T00:00:00+00:00) or the CCSDS days value exceeds the allowed bit width /// (24 bits). - pub fn from_unix_stamp_with_u16_days( + pub fn from_unix_time_with_u16_days( unix_stamp: &UnixTime, submillis_prec: SubmillisPrecision, ) -> Result { @@ -960,13 +960,13 @@ impl CdsTime { Self::from_dt_generic_ps_prec(dt, LengthOfDaySegment::Short16Bits) } - /// Like [Self::from_now_with_u16_days] but with microsecond sub-millisecond precision. + /// Like [Self::now_with_u16_days] but with microsecond sub-millisecond precision. #[cfg(feature = "std")] - pub fn from_now_with_u16_days_us_precision() -> Result { - Self::from_now_generic_us_prec(LengthOfDaySegment::Short16Bits) + pub fn now_with_u16_days_us_precision() -> Result { + Self::now_generic_with_us_prec(LengthOfDaySegment::Short16Bits) } - /// Like [Self::from_now_with_u16_days] but with picosecond sub-millisecond precision. + /// Like [Self::now_with_u16_days] but with picosecond sub-millisecond precision. #[cfg(feature = "std")] pub fn from_now_with_u16_days_ps_precision() -> Result { Self::from_now_generic_ps_prec(LengthOfDaySegment::Short16Bits) @@ -1608,14 +1608,14 @@ mod tests { #[test] fn test_time_now() { - let timestamp_now = CdsTime::from_now_with_u16_days().unwrap(); + let timestamp_now = CdsTime::now_with_u16_days().unwrap(); let compare_stamp = chrono::Utc::now(); generic_now_test(timestamp_now, compare_stamp); } #[test] fn test_time_now_us_prec() { - let timestamp_now = CdsTime::from_now_with_u16_days_us_precision().unwrap(); + let timestamp_now = CdsTime::now_with_u16_days_us_precision().unwrap(); let compare_stamp = chrono::Utc::now(); generic_now_test(timestamp_now, compare_stamp); } @@ -1636,7 +1636,7 @@ mod tests { #[test] fn test_time_now_ps_prec_u24_days() { - let timestamp_now = CdsTime::from_now_with_u24_days_ps_precision().unwrap(); + let timestamp_now = CdsTime::now_with_u24_days_ps_precision().unwrap(); let compare_stamp = chrono::Utc::now(); generic_now_test(timestamp_now, compare_stamp); } @@ -1921,7 +1921,7 @@ mod tests { fn test_creation_from_unix_stamp_0_u16_days() { let unix_secs = 0; let subsec_millis = 0; - let time_provider = CdsTime::from_unix_stamp_with_u16_days( + let time_provider = CdsTime::from_unix_time_with_u16_days( &UnixTime::new(unix_secs, subsec_millis), SubmillisPrecision::Absent, ) @@ -1933,7 +1933,7 @@ mod tests { fn test_creation_from_unix_stamp_0_u24_days() { let unix_secs = 0; let subsec_millis = 0; - let time_provider = CdsTime::from_unix_stamp_with_u24_days( + let time_provider = CdsTime::from_unix_time_with_u24_day( &UnixTime::new(unix_secs, subsec_millis), SubmillisPrecision::Absent, ) @@ -1950,11 +1950,9 @@ mod tests { .unwrap() .and_local_timezone(chrono::Utc) .unwrap(); - let time_provider = CdsTime::from_unix_stamp_with_u16_days( - &datetime_utc.into(), - SubmillisPrecision::Absent, - ) - .expect("creating provider from unix stamp failed"); + let time_provider = + CdsTime::from_unix_time_with_u16_days(&datetime_utc.into(), SubmillisPrecision::Absent) + .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); @@ -1970,7 +1968,7 @@ 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 = CdsTime::from_unix_stamp_with_u16_days( + let time_provider = CdsTime::from_unix_time_with_u16_days( &UnixTime::new(unix_secs, subsec_millis), SubmillisPrecision::Absent, ) @@ -1982,7 +1980,7 @@ 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 CdsTime::from_unix_stamp_with_u16_days( + match CdsTime::from_unix_time_with_u16_days( &UnixTime::new(invalid_unix_secs, subsec_millis), SubmillisPrecision::Absent, ) { @@ -2009,7 +2007,7 @@ 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 CdsTime::from_unix_stamp_with_u16_days( + match CdsTime::from_unix_time_with_u16_days( &UnixTime::new(unix_secs as i64, subsec_millis), SubmillisPrecision::Absent, ) { @@ -2309,7 +2307,7 @@ mod tests { #[test] #[cfg(feature = "serde")] fn test_serialization() { - let stamp_now = CdsTime::from_now_with_u16_days().expect("Error retrieving time"); + let stamp_now = CdsTime::now_with_u16_days().expect("Error retrieving time"); let val = to_allocvec(&stamp_now).expect("Serializing timestamp failed"); assert!(val.len() > 0); let stamp_deser: CdsTime = from_bytes(&val).expect("Stamp deserialization failed"); diff --git a/src/time/cuc.rs b/src/time/cuc.rs index a14aeb3..f962361 100644 --- a/src/time/cuc.rs +++ b/src/time/cuc.rs @@ -249,7 +249,7 @@ impl FractionalPart { /// const LEAP_SECONDS: u32 = 37; /// /// // Highest fractional resolution -/// let timestamp_now = CucTime::from_now(FractionalResolution::SixtyNs, LEAP_SECONDS) +/// let timestamp_now = CucTime::now(FractionalResolution::SixtyNs, LEAP_SECONDS) /// .expect("creating cuc stamp failed"); /// let mut raw_stamp = [0; 16]; /// { @@ -359,7 +359,7 @@ impl CucTime { /// must be applied on top of the UTC based time retrieved from the system in addition to the /// conversion to the CCSDS epoch. #[cfg(feature = "std")] - pub fn from_now( + pub fn now( fraction_resolution: FractionalResolution, leap_seconds: u32, ) -> Result { @@ -430,15 +430,15 @@ impl CucTime { /// Generates a CUC timestamp from a UNIX timestamp with a width of 4. This width is able /// to accomodate all possible UNIX timestamp values. - pub fn from_unix_stamp( - unix_stamp: &UnixTime, + pub fn from_unix_time( + unix_time: &UnixTime, res: FractionalResolution, leap_seconds: u32, ) -> Result { - let counter = unix_epoch_to_ccsds_epoch(unix_stamp.secs); + let counter = unix_epoch_to_ccsds_epoch(unix_time.secs); // Negative CCSDS epoch is invalid. if counter < 0 { - return Err(DateBeforeCcsdsEpochError(*unix_stamp).into()); + return Err(DateBeforeCcsdsEpochError(*unix_time).into()); } // We already excluded negative values, so the conversion to u64 should always work. let mut counter = u32::try_from(counter).map_err(|_| CucError::InvalidCounter { @@ -449,7 +449,7 @@ impl CucTime { .checked_add(leap_seconds) .ok_or(CucError::LeapSecondCorrectionError)?; let fractions = - fractional_part_from_subsec_ns(res, unix_stamp.subsec_millis() as u64 * 10_u64.pow(6)); + fractional_part_from_subsec_ns(res, unix_time.subsec_millis() as u64 * 10_u64.pow(6)); Self::new_generic(WidthCounterPair(4, counter as u32), fractions) } @@ -913,7 +913,7 @@ mod tests { #[test] fn test_datetime_now() { let now = chrono::Utc::now(); - let cuc_now = CucTime::from_now(FractionalResolution::SixtyNs, LEAP_SECONDS); + let cuc_now = CucTime::now(FractionalResolution::SixtyNs, LEAP_SECONDS); assert!(cuc_now.is_ok()); let cuc_now = cuc_now.unwrap(); let ccsds_cuc = cuc_now.to_leap_sec_helper(LEAP_SECONDS); @@ -1251,6 +1251,7 @@ mod tests { ); assert_eq!(stamp.fractions().counter(), 0); let res = stamp.update_from_now(LEAP_SECONDS); + assert!(res.is_ok()); } @@ -1382,9 +1383,8 @@ mod tests { #[test] fn from_unix_stamp() { let unix_stamp = UnixTime::new(0, 0); - let cuc = - CucTime::from_unix_stamp(&unix_stamp, FractionalResolution::Seconds, LEAP_SECONDS) - .expect("failed to create cuc from unix stamp"); + let cuc = CucTime::from_unix_time(&unix_stamp, FractionalResolution::Seconds, LEAP_SECONDS) + .expect("failed to create cuc from unix stamp"); assert_eq!( cuc.counter(), (-DAYS_CCSDS_TO_UNIX * SECONDS_PER_DAY as i32) as u32 + LEAP_SECONDS diff --git a/src/time/mod.rs b/src/time/mod.rs index dc7ef42..139e816 100644 --- a/src/time/mod.rs +++ b/src/time/mod.rs @@ -345,7 +345,7 @@ impl UnixTime { } #[cfg(feature = "std")] - pub fn from_now() -> Result { + pub fn now() -> Result { let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?; let epoch = now.as_secs(); Ok(Self::new(epoch as i64, now.subsec_nanos())) @@ -356,7 +356,7 @@ impl UnixTime { self.secs as f64 + (self.subsec_nanos as f64 / 1_000_000_000.0) } - pub fn secs(&self) -> i64 { + pub fn as_secs(&self) -> i64 { self.secs } @@ -367,7 +367,7 @@ impl UnixTime { #[cfg(feature = "timelib")] pub fn timelib_date_time(&self) -> Result { - Ok(time::OffsetDateTime::from_unix_timestamp(self.secs())? + Ok(time::OffsetDateTime::from_unix_timestamp(self.as_secs())? + time::Duration::nanoseconds(self.subsec_nanos().into())) } @@ -649,7 +649,7 @@ mod tests { fn test_addition() { let mut stamp0 = UnixTime::new_only_secs(1); stamp0 += Duration::from_secs(5); - assert_eq!(stamp0.secs(), 6); + assert_eq!(stamp0.as_secs(), 6); assert_eq!(stamp0.subsec_millis(), 0); let stamp1 = stamp0 + Duration::from_millis(500); assert_eq!(stamp1.secs, 6); @@ -678,7 +678,7 @@ mod tests { #[test] fn test_from_now() { - let stamp_now = UnixTime::from_now().unwrap(); + let stamp_now = UnixTime::now().unwrap(); let dt_now = stamp_now.chrono_date_time().unwrap(); assert!(dt_now.year() >= 2020); }