diff --git a/src/time.rs b/src/time.rs index 99bb532..e399b3d 100644 --- a/src/time.rs +++ b/src/time.rs @@ -270,25 +270,39 @@ impl TimeReader for CdsShortTimeProvider { /// Module to generate the ASCII timecodes specified in /// [CCSDS 301.0-B-4](https://public.ccsds.org/Pubs/301x0b4e1.pdf) section 3.5 . +/// See [chrono::DateTime::format] for a usage example of the generated +/// [chrono::format::DelayedFormat] structs. pub mod ascii { use chrono::format::{DelayedFormat, StrftimeItems}; use chrono::{DateTime, Utc}; /// Tuple of format string and formatted size for time code A. /// - /// YYYY-MM-DDThh:mm:ss.ddd + /// Format: YYYY-MM-DDThh:mm:ss.ddd /// /// Three digits are used for the decimal fraction pub const FMT_STR_CODE_A_WITH_SIZE: (&str, usize) = ("%FT%T%.3f", 23); /// Tuple of format string and formatted size for time code A. /// - /// YYYY-MM-DDThh:mm:ss.dddZ + /// Format: YYYY-MM-DDThh:mm:ss.dddZ /// /// Three digits are used for the decimal fraction and a terminator is added at the end. pub const FMT_STR_CODE_A_TERMINATED_WITH_SIZE: (&str, usize) = ("%FT%T%.3fZ", 24); + /// Tuple of format string and formatted size for time code A. + /// + /// Format: YYYY-DDDThh:mm:ss.ddd + /// + /// Three digits are used for the decimal fraction + pub const FMT_STR_CODE_B_WITH_SIZE: (&str, usize) = ("%Y-%jT%T%.3f", 21); + /// Tuple of format string and formatted size for time code A. + /// + /// Format: YYYY-DDDThh:mm:ss.dddZ + /// + /// Three digits are used for the decimal fraction and a terminator is added at the end. + pub const FMT_STR_CODE_B_TERMINATED_WITH_SIZE: (&str, usize) = ("%Y-%jT%T%.3fZ", 22); + /// Generates a time code formatter using the [FMT_STR_CODE_A_WITH_SIZE] format. - /// See [chrono::DateTime::format] for a usage example. #[cfg(feature = "alloc")] #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] pub fn generate_time_code_a(date: &DateTime) -> DelayedFormat> { @@ -296,7 +310,6 @@ pub mod ascii { } /// Generates a time code formatter using the [FMT_STR_CODE_A_TERMINATED_WITH_SIZE] format. - /// See [chrono::DateTime::format] for a usage example. #[cfg(feature = "alloc")] #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] pub fn generate_time_code_a_terminated( @@ -304,6 +317,22 @@ pub mod ascii { ) -> DelayedFormat> { date.format(FMT_STR_CODE_A_TERMINATED_WITH_SIZE.0) } + + /// Generates a time code formatter using the [FMT_STR_CODE_B_WITH_SIZE] format. + #[cfg(feature = "alloc")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] + pub fn generate_time_code_b(date: &DateTime) -> DelayedFormat> { + date.format(FMT_STR_CODE_B_WITH_SIZE.0) + } + + /// Generates a time code formatter using the [FMT_STR_CODE_B_TERMINATED_WITH_SIZE] format. + #[cfg(feature = "alloc")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] + pub fn generate_time_code_b_terminated( + date: &DateTime, + ) -> DelayedFormat> { + date.format(FMT_STR_CODE_B_TERMINATED_WITH_SIZE.0) + } } #[cfg(all(test, feature = "std"))] @@ -317,19 +346,18 @@ mod tests { use postcard::{from_bytes, to_allocvec}; #[test] - fn test_ascii_timestamp_unterminated() { + fn test_ascii_timestamp_a_unterminated() { let date = Utc::now(); let stamp_formatter = ascii::generate_time_code_a(&date); let stamp = format!("{}", stamp_formatter); let t_sep = stamp.find("T"); assert!(t_sep.is_some()); assert_eq!(t_sep.unwrap(), 10); - assert_eq!(stamp.len(), 23); assert_eq!(stamp.len(), ascii::FMT_STR_CODE_A_WITH_SIZE.1); } #[test] - fn test_ascii_timestamp_terminated() { + fn test_ascii_timestamp_a_terminated() { let date = Utc::now(); let stamp_formatter = ascii::generate_time_code_a_terminated(&date); let stamp = format!("{}", stamp_formatter); @@ -338,11 +366,41 @@ mod tests { assert_eq!(t_sep.unwrap(), 10); let z_terminator = stamp.find("Z"); assert!(z_terminator.is_some()); - assert_eq!(z_terminator.unwrap(), 23); - assert_eq!(stamp.len(), 24); + assert_eq!( + z_terminator.unwrap(), + ascii::FMT_STR_CODE_A_TERMINATED_WITH_SIZE.1 - 1 + ); assert_eq!(stamp.len(), ascii::FMT_STR_CODE_A_TERMINATED_WITH_SIZE.1); } + #[test] + fn test_ascii_timestamp_b_unterminated() { + let date = Utc::now(); + let stamp_formatter = ascii::generate_time_code_b(&date); + let stamp = format!("{}", stamp_formatter); + let t_sep = stamp.find("T"); + assert!(t_sep.is_some()); + assert_eq!(t_sep.unwrap(), 8); + assert_eq!(stamp.len(), ascii::FMT_STR_CODE_B_WITH_SIZE.1); + } + + #[test] + fn test_ascii_timestamp_b_terminated() { + let date = Utc::now(); + let stamp_formatter = ascii::generate_time_code_b_terminated(&date); + let stamp = format!("{}", stamp_formatter); + let t_sep = stamp.find("T"); + assert!(t_sep.is_some()); + assert_eq!(t_sep.unwrap(), 8); + let z_terminator = stamp.find("Z"); + assert!(z_terminator.is_some()); + assert_eq!( + z_terminator.unwrap(), + ascii::FMT_STR_CODE_B_TERMINATED_WITH_SIZE.1 - 1 + ); + assert_eq!(stamp.len(), ascii::FMT_STR_CODE_B_TERMINATED_WITH_SIZE.1); + } + #[test] fn test_creation() { assert_eq!(unix_to_ccsds_days(DAYS_CCSDS_TO_UNIX), 0);