diff options
Diffstat (limited to 'crates/core/c8y_smartrest/src/smartrest_deserializer.rs')
-rw-r--r-- | crates/core/c8y_smartrest/src/smartrest_deserializer.rs | 79 |
1 files changed, 78 insertions, 1 deletions
diff --git a/crates/core/c8y_smartrest/src/smartrest_deserializer.rs b/crates/core/c8y_smartrest/src/smartrest_deserializer.rs index c995c7d1..fea01538 100644 --- a/crates/core/c8y_smartrest/src/smartrest_deserializer.rs +++ b/crates/core/c8y_smartrest/src/smartrest_deserializer.rs @@ -1,10 +1,11 @@ -use crate::error::SmartRestDeserializerError; +use crate::error::{SMCumulocityMapperError, SmartRestDeserializerError}; use agent_interface::{SoftwareModule, SoftwareModuleUpdate, SoftwareUpdateRequest}; use csv::ReaderBuilder; use download::DownloadInfo; use serde::de::Error; use serde::{Deserialize, Deserializer, Serialize}; use std::convert::{TryFrom, TryInto}; +use std::path::PathBuf; use time::{format_description, OffsetDateTime}; #[derive(Debug)] @@ -287,12 +288,50 @@ impl SmartRestJwtResponse { } } +/// Returns a date time object from a file path or file-path-like string +/// a typical file stem looks like this: "software-list-2021-10-27T10:29:58Z" +/// +/// # Examples: +/// ``` +/// use std::path::PathBuf; +/// use crate::c8y_smartrest::smartrest_deserializer::get_datetime_from_file_path; +/// +/// let mut path = PathBuf::new(); +/// path.push("/path/to/file/with/date/in/path-2021-10-27T10:29:58Z"); +/// let path_bufdate_time = get_datetime_from_file_path(&path).unwrap(); +/// ``` +pub fn get_datetime_from_file_path( + log_path: &PathBuf, +) -> Result<OffsetDateTime, SMCumulocityMapperError> { + if let Some(stem_string) = log_path.file_stem().and_then(|s| s.to_str()) { + // a typical file stem looks like this: software-list-2021-10-27T10:29:58Z. + // to extract the date, rsplit string on "-" and take (last) 3 + let mut stem_string_vec = stem_string.rsplit('-').take(3).collect::<Vec<_>>(); + // reverse back the order (because of rsplit) + stem_string_vec.reverse(); + // join on '-' to get the date string + let date_string = stem_string_vec.join("-"); + let dt = OffsetDateTime::parse(&date_string, &format_description::well_known::Rfc3339)?; + + return Ok(dt); + } + match log_path.to_str() { + Some(path) => Err(SMCumulocityMapperError::InvalidDateInFileName( + path.to_string(), + ))?, + None => Err(SMCumulocityMapperError::InvalidUtf8Path)?, + } +} + #[cfg(test)] mod tests { use super::*; use agent_interface::*; use assert_json_diff::*; use serde_json::json; + use std::fs::File; + use std::io::Write; + use std::str::FromStr; use test_case::test_case; // To avoid using an ID randomly generated, which is not convenient for testing. @@ -568,4 +607,42 @@ mod tests { let log = SmartRestRestartRequest::from_smartrest(&smartrest); assert!(log.is_ok()); } + + #[test_case("/path/to/software-list-2021-10-27T10:44:44Z.log")] + #[test_case("/path/to/tedge/agent/software-update-2021-10-25T07:45:41Z.log")] + #[test_case("/path/to/another-variant-2021-10-25T07:45:41Z.log")] + #[test_case("/yet-another-variant-2021-10-25T07:45:41Z.log")] + fn test_datetime_parsing_from_path(file_path: &str) { + // checking that `get_date_from_file_path` unwraps a `chrono::NaiveDateTime` object. + // this should return an Ok Result. + let path_buf = PathBuf::from_str(file_path).unwrap(); + let path_buf_datetime = get_datetime_from_file_path(&path_buf); + assert!(path_buf_datetime.is_ok()); + } + + #[test_case("/path/to/software-list-2021-10-27-10:44:44Z.log")] + #[test_case("/path/to/tedge/agent/software-update-10-25-2021T07:45:41Z.log")] + #[test_case("/path/to/another-variant-07:45:41Z-2021-10-25T.log")] + #[test_case("/yet-another-variant-2021-10-25T07:45Z.log")] + fn test_datetime_parsing_from_path_fail(file_path: &str) { + // checking that `get_date_from_file_path` unwraps a `chrono::NaiveDateTime` object. + // this should return an err. + let path_buf = PathBuf::from_str(file_path).unwrap(); + let path_buf_datetime = get_datetime_from_file_path(&path_buf); + assert!(path_buf_datetime.is_err()); + } + + fn parse_file_names_from_log_content(log_content: &str) -> [&str; 5] { + let mut files: Vec<&str> = vec![]; + for line in log_content.lines() { + if line.contains("filename: ") { + let filename: &str = line.split("filename: ").last().unwrap(); + files.push(filename); + } + } + match files.try_into() { + Ok(arr) => arr, + Err(_) => panic!("Could not convert to Array &str, size 5"), + } + } } |