diff --git a/Cargo.lock b/Cargo.lock index a410a46..98951ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -338,6 +338,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + [[package]] name = "env_filter" version = "0.1.0" @@ -525,6 +531,15 @@ version = "1.70.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -649,6 +664,7 @@ dependencies = [ "clap_derive", "csv", "env_logger", + "itertools", "log", "predicates", "regex", diff --git a/Cargo.toml b/Cargo.toml index 63b6943..887075f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ clap_derive = "4.5" log = "0.4" env_logger = "0.11.3" clap-verbosity-flag = "2.2" +itertools = "0.13" anyhow = "1.0" chrono = { version = "0.4", features = ["serde"] } semver = { version = "1.0", features = ["serde"] } diff --git a/README.md b/README.md index 0bb5cbe..828d003 100644 --- a/README.md +++ b/README.md @@ -30,5 +30,6 @@ cargo doc --open - split into mods(maybe as lib crates) - add csv check/validate subcommand - skew measurement? +- skew measurement test check `TODO`s in comments. diff --git a/src/main.rs b/src/main.rs index f15fa1e..8903cef 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,8 @@ use semver::Version; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, DisplayFromStr}; +mod skew; + /// PS Board QAQC shift related commands. #[derive(Parser, Debug)] #[command(version, about, long_about = None)] @@ -520,7 +522,11 @@ fn main() -> Result<()> { return Err(anyhow!("Invalid csv")); }; } - Commands::AddSkew { logfile, outfile } => todo!("Not implemented"), + Commands::AddSkew { logfile, outfile } => { + let skew = skew::parse_count_file(logfile).context("Error during getting skew")?; + trace!("Skew: {}", skew); + todo!("Not implemented") + } } Ok(()) } diff --git a/src/skew.rs b/src/skew.rs new file mode 100644 index 0000000..a47e8e0 --- /dev/null +++ b/src/skew.rs @@ -0,0 +1,78 @@ +use anyhow::{Context, Result}; +use itertools::{self, Itertools}; +use std::{ + fs::File, + io::{BufRead, BufReader}, + path::PathBuf, +}; + +fn parse_single_line(l: String) -> Result<(f64, u32, u32)> { + let mut splitted = l.split_whitespace(); + let delay: f64 = splitted.next().context("No value found")?.parse()?; + let high_count: u32 = splitted.next().context("No value found")?.parse()?; + let low_count: u32 = splitted.next().context("No value found")?.parse()?; + assert!(splitted.next().is_none()); + Ok((delay, high_count, low_count)) +} + +fn parse_counts(f: impl BufRead) -> Result { + let delay = f + .lines() + .filter_map(|l| parse_single_line(l.ok()?).ok()) + .tuple_windows() + .find(|((_, high1, _), (_, high2, _))| *high1 < 500 && *high2 >= 500) + .context("Failed to get rise edge")? + .1 + .0; + Ok(delay) +} + +/// Read clock scan file and get skew. +pub fn parse_count_file(filename: PathBuf) -> Result { + let buf_reader = BufReader::new( + File::open(filename.clone()) + .context(format!("Error opening file {}", filename.display()))?, + ); + parse_counts(buf_reader) +} + +#[cfg(test)] +mod test { + use super::parse_counts; + #[test] + fn test_parse_counts1() { + let file = " + 0.1 0 1000 + 0.2 10 990 + 0.3 470 530 + 0.4 500 500 + 0.5 510 490 + 0.6 900 100 + 0.7 1000 0 + " + .as_bytes(); + assert_eq!(parse_counts(file).unwrap(), 0.4); + let file2 = " + 0.1 0 1000 + 0.2 10 990 + 0.3 470 530 + 0.4 499 501 + 0.5 510 490 + 0.6 900 100 + 0.7 1000 0 + " + .as_bytes(); + assert_eq!(parse_counts(file2).unwrap(), 0.5); + let file3 = " + 0.1 0 1000 + 0.2 10 990 + 0.3 470 530 + 0.4 501 499 + 0.5 510 490 + 0.6 900 100 + 0.7 1000 0 + " + .as_bytes(); + assert_eq!(parse_counts(file3).unwrap(), 0.4); + } +}