From 58a6cbd68906b9c0fb3dd4007d064b27a05f5039 Mon Sep 17 00:00:00 2001 From: Cutieguwu Date: Thu, 20 Feb 2025 20:33:46 -0500 Subject: [PATCH 1/4] Added basis for unit tests. Noted required unit tests to imlpement. --- src/main.rs | 25 +++++++++++++++++++----- src/mapping.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++++- src/recovery.rs | 24 ++++++++++++++++------- 3 files changed, 87 insertions(+), 13 deletions(-) diff --git a/src/main.rs b/src/main.rs index 295d549..888688e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -122,9 +122,9 @@ fn main() { } }; - let recover_tool = Recover::new(config, input, output, map); + let mut recover_tool = Recover::new(config, input, output, map); - recover_tool.run_full(); + recover_tool.run(); todo!("Recovery, Map saving, and closure of all files."); } @@ -152,10 +152,25 @@ fn get_path( /// Get length of data stream. /// Physical length of data stream in bytes /// (multiple of sector_size, rather than actual). -fn get_stream_length(file: &mut S) -> io::Result { - let len = file.seek(SeekFrom::End(0))?; +fn get_stream_length(input: &mut S) -> io::Result { + let len = input.seek(SeekFrom::End(0))?; - let _ = file.seek(SeekFrom::Start(0)); + let _ = input.seek(SeekFrom::Start(0)); Ok(len) +} + + +#[cfg(test)] +#[allow(unused)] +mod tests { + use super::*; + + // Test for get_path + // Need to determine how to package files to test with, or at least + // how to test with PathBuf present. + // Test must also check unwrapping of file name, not just generation. + + // Test for get_stream_length + // Need to determine how to test with Seek-able objects. } \ No newline at end of file diff --git a/src/mapping.rs b/src/mapping.rs index 763be02..0e60228 100644 --- a/src/mapping.rs +++ b/src/mapping.rs @@ -69,6 +69,37 @@ impl From for MapCluster { } } +impl MapCluster { + /// Breaks apart into a vec of clusters, + /// each of cluster_size, excepting last. + pub fn subdivide(&mut self, cluster_len: usize) -> Vec { + let domain_len = self.domain.len(); + let mut start = self.domain.start; + let mut clusters: Vec = vec![]; + + for _ in 0..(domain_len as f64 / cluster_len as f64).floor() as usize { + clusters.push(MapCluster { + domain: Domain { + start: start, + end: start + cluster_len, + }, + stage: self.stage, + }); + + start += cluster_len; + } + + clusters.push(MapCluster { + domain: Domain { + start: start, + end: self.domain.end, + }, + stage: self.stage, + }); + + clusters + } +} #[derive(Clone, Copy, Debug, Deserialize, PartialEq, PartialOrd)] pub enum Stage { @@ -125,7 +156,7 @@ impl MapFile { } /// Recalculate cluster mappings. - fn update(&mut self, new_cluster: Cluster) { + fn update(&mut self, new_cluster: Cluster) -> &mut Self { let mut new_map: Vec = vec![MapCluster::from(new_cluster.to_owned())]; for map_cluster in self.map.iter() { @@ -185,6 +216,7 @@ impl MapFile { } self.map = new_map; + self } /// Get current recovery stage. @@ -266,4 +298,21 @@ impl MapFile { self.map = new_map; self } +} + + +#[cfg(test)] +#[allow(unused)] +mod tests { + use super::*; + + // Test for MapCluster::subdivide() + + // Test for MapFile::update() + + // Test for MapFile::get_stage() + + // Test for MapFile::get_clusters() + + // Test for MapFile::defrag() } \ No newline at end of file diff --git a/src/recovery.rs b/src/recovery.rs index 5095905..726b0ac 100644 --- a/src/recovery.rs +++ b/src/recovery.rs @@ -46,20 +46,30 @@ impl Recover { } /// Recover media from blank slate. - pub fn run_full(self) {} - - /// Recover media given a partial recovery. - pub fn run_limited(self) {} + pub fn run(&mut self) -> &mut Self { + self + } /// Attempt to copy all untested blocks. - fn copy_untested(self) { - + fn copy_untested(&mut self) -> &mut Self { + + self } /// Set buffer capacities as cluster length in bytes. /// Varies depending on the recovery stage. - fn set_buf_capacity(&mut self) { + fn set_buf_capacity(&mut self) -> &mut Self { self.buf_capacity = (self.config.sector_size * self.config.cluster_length) as usize; + + self } } + +#[cfg(test)] +#[allow(unused)] +mod tests { + use super::*; + + // Test for Recover::set_buf_capacity +} \ No newline at end of file -- 2.49.1 From b890d74cb77406b4c591842936efeae788cd23f5 Mon Sep 17 00:00:00 2001 From: Cutieguwu Date: Mon, 24 Feb 2025 14:20:18 -0500 Subject: [PATCH 2/4] Reviewed dependency tree. --- Cargo.lock | 516 ++++++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 15 +- 2 files changed, 527 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a33c94..f91fe95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,18 +2,54 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "anstyle" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +[[package]] +name = "anyhow" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" + +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + +[[package]] +name = "base62" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10e52a7bcb1d6beebee21fb5053af9e3cbb7a7ed1a4909e534040e676437ab1f" +dependencies = [ + "rustversion", +] + [[package]] name = "base64" version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.8.0" @@ -23,6 +59,16 @@ dependencies = [ "serde", ] +[[package]] +name = "bstr" +version = "1.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "clap" version = "4.5.30" @@ -62,12 +108,126 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "either" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7914353092ddf589ad78f25c5c1c21b7f80b0ff8621e7c814c3485b5306da9d" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "globset" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags 1.3.2", + "ignore", + "walkdir", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "ignore" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata", + "same-file", + "walkdir", + "winapi-util", +] + +[[package]] +name = "indexmap" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + [[package]] name = "kramer" version = "0.1.0" @@ -75,15 +235,59 @@ dependencies = [ "clap", "libc", "ron", + "rust-i18n", "serde", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +[[package]] +name = "libyml" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3302702afa434ffa30847a83305f0a69d6abd74293b6554c18ec85c7ef30c980" +dependencies = [ + "anyhow", + "version_check", +] + +[[package]] +name = "log" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "normpath" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "once_cell" +version = "1.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" + [[package]] name = "proc-macro2" version = "1.0.92" @@ -102,6 +306,35 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + [[package]] name = "ron" version = "0.8.1" @@ -109,11 +342,86 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64", - "bitflags", + "bitflags 2.8.0", "serde", "serde_derive", ] +[[package]] +name = "rust-i18n" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71b3a6e1c6565b77c86d868eea3068b0eb39582510f9c78cfbd5c67bd36fda9b" +dependencies = [ + "globwalk", + "once_cell", + "regex", + "rust-i18n-macro", + "rust-i18n-support", + "smallvec", +] + +[[package]] +name = "rust-i18n-macro" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6180d8506af2b485ffc1eab7fc6d15678336a694f2b5efac5f2ca78c52928275" +dependencies = [ + "glob", + "once_cell", + "proc-macro2", + "quote", + "rust-i18n-support", + "serde", + "serde_json", + "serde_yml", + "syn", +] + +[[package]] +name = "rust-i18n-support" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938f16094e2b09e893b1f85c9da251739a832d4272a5957217977da3a0713bb6" +dependencies = [ + "arc-swap", + "base62", + "globwalk", + "itertools", + "lazy_static", + "normpath", + "once_cell", + "proc-macro2", + "regex", + "serde", + "serde_json", + "serde_yml", + "siphasher", + "toml", + "triomphe", +] + +[[package]] +name = "rustversion" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" + +[[package]] +name = "ryu" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "serde" version = "1.0.218" @@ -134,6 +442,60 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_yml" +version = "0.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd" +dependencies = [ + "indexmap", + "itoa", + "libyml", + "memchr", + "ryu", + "serde", + "version_check", +] + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "smallvec" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "strsim" version = "0.11.1" @@ -151,8 +513,160 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "toml" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "triomphe" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" +dependencies = [ + "arc-swap", + "serde", + "stable_deref_trait", +] + [[package]] name = "unicode-ident" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" +dependencies = [ + "memchr", +] diff --git a/Cargo.toml b/Cargo.toml index 320c14b..b6ae5bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,13 +4,18 @@ version = "0.1.0" edition = "2021" [dependencies] +# NOTE: +# = X.X.X is the version used in testing. +# Use this version for greatest compatibility. +# # For clap info, see [dependencies.clap] +# For serde info, see [dependencies.serde] libc = "0.2.169" -ron = "0.8.1" -serde = { version = "~1.0.217", features = ["derive"] } +ron = "0.8.1, >=0.8, <0.9" +rust-i18n = "3.1.3" [dependencies.clap] -version = "~4.5.27" +version = "4.5.30, >=4.5.27, <=4.5.30" default-features = false features = [ # From default features collection @@ -23,3 +28,7 @@ features = [ # Optional features "derive", ] + +[dependencies.serde] +version = "1.0.218, >=1.0.217, <=1.0.218" +features = ["derive"] -- 2.49.1 From 93e74ce2d281ba897b482fde8c4af5c3b5941bf1 Mon Sep 17 00:00:00 2001 From: Cutieguwu Date: Mon, 24 Feb 2025 14:20:46 -0500 Subject: [PATCH 3/4] Began writing unit tests. --- src/mapping.rs | 164 ++++++++++++++++++++++++++++++++++++++++++++++-- src/recovery.rs | 7 ++- 2 files changed, 165 insertions(+), 6 deletions(-) diff --git a/src/mapping.rs b/src/mapping.rs index 0e60228..a46a148 100644 --- a/src/mapping.rs +++ b/src/mapping.rs @@ -7,7 +7,7 @@ use crate::FB_SECTOR_SIZE; /// Domain, in sectors. /// Requires sector_size to be provided elsewhere for conversion to bytes. -#[derive(Clone, Copy, Debug, Deserialize)] +#[derive(Clone, Copy, Debug, Deserialize, PartialEq)] pub struct Domain { pub start: usize, pub end: usize, @@ -26,6 +26,7 @@ impl Domain { } } + /// A map for data stored in memory for processing and saving to disk. #[derive(Clone, Debug, Deserialize)] pub struct Cluster { @@ -48,7 +49,7 @@ impl Default for Cluster { /// Map for data stored on disk. /// Rather have a second cluster type than inflating size /// of output map by defining Option::None constantly. -#[derive(Clone, Copy, Debug, Deserialize)] +#[derive(Clone, Copy, Debug, Deserialize, PartialEq)] pub struct MapCluster { pub domain: Domain, pub stage: Stage, @@ -99,8 +100,14 @@ impl MapCluster { clusters } + + pub fn set_stage(&mut self, stage: Stage) -> &mut Self { + self.stage = stage; + self + } } + #[derive(Clone, Copy, Debug, Deserialize, PartialEq, PartialOrd)] pub enum Stage { Untested, @@ -115,7 +122,7 @@ impl Default for Stage { } -#[derive(Clone, Debug, Deserialize)] +#[derive(Clone, Debug, Deserialize, PartialEq)] pub struct MapFile { pub sector_size: u16, pub domain: Domain, @@ -243,7 +250,7 @@ impl MapFile { } /// Get clusters of common stage. - pub fn get_clusters(self, stage: Stage) -> Vec { + pub fn get_clusters(&self, stage: Stage) -> Vec { self.map.iter() .filter_map(|mc| { if mc.stage == stage { Some(mc.to_owned()) } else { None } @@ -302,8 +309,9 @@ impl MapFile { #[cfg(test)] -#[allow(unused)] mod tests { + use ron::Map; + use super::*; // Test for MapCluster::subdivide() @@ -311,8 +319,154 @@ mod tests { // Test for MapFile::update() // Test for MapFile::get_stage() + #[test] + fn test_get_stage() { + use std::vec; + + let mut mf = MapFile::default(); + let mut mf_stage = mf.get_stage(); + + // If this fails here, there's something SERIOUSLY wrong. + assert!( + mf_stage == Stage::Untested, + "Determined stage to be {:?}, when {:?} was expeccted.", + mf_stage, Stage::Untested + ); + + + let stages = vec![ + Stage::Damaged, + Stage::ForIsolation(1), + Stage::ForIsolation(0), + Stage::Untested, + ]; + + mf.map = vec![]; + + for stage in stages { + mf.map.push(*MapCluster::default().set_stage(stage)); + + mf_stage = mf.get_stage(); + + assert!( + stage == mf_stage, + "Expected stage to be {:?}, determined {:?} instead.", + stage, mf_stage + ) + } + } // Test for MapFile::get_clusters() + #[test] + fn test_get_clusters() { + let mut mf = MapFile::default(); + + mf.map = vec![ + *MapCluster::default().set_stage(Stage::Damaged), + *MapCluster::default().set_stage(Stage::ForIsolation(0)), + *MapCluster::default().set_stage(Stage::ForIsolation(1)), + MapCluster::default(), + MapCluster::default(), + *MapCluster::default().set_stage(Stage::ForIsolation(1)), + *MapCluster::default().set_stage(Stage::ForIsolation(0)), + *MapCluster::default().set_stage(Stage::Damaged), + ]; + + let stages = vec![ + Stage::Damaged, + Stage::ForIsolation(1), + Stage::ForIsolation(0), + Stage::Untested, + ]; + + for stage in stages { + let expected = vec![ + *MapCluster::default().set_stage(stage), + *MapCluster::default().set_stage(stage), + ]; + let recieved = mf.get_clusters(stage); + + assert!( + expected == recieved, + "Expected clusters {:?}, got {:?}.", + expected, recieved + ) + } + } // Test for MapFile::defrag() + #[test] + fn test_defrag() { + let mut mf = MapFile { + sector_size: 1, + domain: Domain { start: 0, end: 8 }, + map: vec![ + MapCluster { + domain: Domain { start: 0, end: 1 }, + stage: Stage::Untested, + }, + MapCluster { + domain: Domain { start: 1, end: 2 }, + stage: Stage::Untested, + }, + MapCluster { + domain: Domain { start: 2, end: 3 }, + stage: Stage::Untested, + }, + MapCluster { + domain: Domain { start: 3, end: 4 }, + stage: Stage::ForIsolation(0), + }, + MapCluster { + domain: Domain { start: 4, end: 5 }, + stage: Stage::ForIsolation(0), + }, + MapCluster { + domain: Domain { start: 5, end: 6 }, + stage: Stage::ForIsolation(1), + }, + MapCluster { + domain: Domain { start: 6, end: 7 }, + stage: Stage::ForIsolation(0), + }, + MapCluster { + domain: Domain { start: 7, end: 8 }, + stage: Stage::Damaged, + }, + ], + }; + + let expected = vec![ + MapCluster { + domain: Domain { start: 0, end: 3 }, + stage: Stage::Untested, + }, + MapCluster { + domain: Domain { start: 3, end: 5 }, + stage: Stage::ForIsolation(0), + }, + MapCluster { + domain: Domain { start: 5, end: 6 }, + stage: Stage::ForIsolation(1), + }, + MapCluster { + domain: Domain { start: 6, end: 7 }, + stage: Stage::ForIsolation(0), + }, + MapCluster { + domain: Domain { start: 7, end: 8 }, + stage: Stage::Damaged, + }, + ]; + + mf.defrag(); + + let recieved = mf.map; + + assert!( + expected == recieved, + "Expected {:?} after defragging, got {:?}.", + expected, recieved + ) + } } \ No newline at end of file diff --git a/src/recovery.rs b/src/recovery.rs index 726b0ac..b62e3ec 100644 --- a/src/recovery.rs +++ b/src/recovery.rs @@ -20,7 +20,12 @@ pub struct Recover { } impl Recover { - pub fn new(config: Args, input: File, output: File, map: MapFile) -> Self { + pub fn new( + config: Args, + input: File, + output: File, + map: MapFile, + ) -> Self { let stage = map.get_stage(); // Temporarily make buffer length one sector. -- 2.49.1 From d74ef1b0fee848224867d152ca10ddb5262bc784 Mon Sep 17 00:00:00 2001 From: Cutieguwu Date: Wed, 26 Feb 2025 11:44:00 -0500 Subject: [PATCH 4/4] Fixed infinite looping of MapFile::defrag method. --- src/mapping.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/mapping.rs b/src/mapping.rs index a46a148..8fd0f11 100644 --- a/src/mapping.rs +++ b/src/mapping.rs @@ -264,41 +264,44 @@ impl MapFile { fn defrag(&mut self) -> &mut Self { let mut new_map: Vec = vec![]; - let mut pos: usize = 0; - // Fetch first cluster. let mut start_cluster = *self.map.iter() - .find(|c| c.domain.start == pos) + .find(|c| c.domain.start == 0) .unwrap(); + // Even though this would be initialized by its first read, // the compiler won't stop whining, and idk how to assert that to it. let mut end_cluster = MapCluster::default(); let mut new_cluster: MapCluster; let mut stage_common: bool; + let mut is_finished = false; - while pos < self.domain.end { + while !is_finished { stage_common = true; // Start a new cluster based on the cluster following // the end of last new_cluster. new_cluster = start_cluster; - // While stage is common, find each trailing cluster. - while stage_common { - // start_cluster was of common stage to end_cluster. + // While stage is common, and not finished, + // find each trailing cluster. + while stage_common && !is_finished { end_cluster = start_cluster; - start_cluster = *self.map.iter() - .find(|c| end_cluster.domain.end == c.domain.start) - .unwrap(); + if end_cluster.domain.end != self.domain.end { + start_cluster = *self.map.iter() + .find(|c| end_cluster.domain.end == c.domain.start) + .unwrap(); - stage_common = new_cluster.stage == start_cluster.stage + stage_common = new_cluster.stage == start_cluster.stage + } else { + is_finished = true; + } } // Set the new ending, encapsulating any clusters of common stage. new_cluster.domain.end = end_cluster.domain.end; - pos = new_cluster.domain.end; new_map.push(new_cluster); } @@ -310,8 +313,6 @@ impl MapFile { #[cfg(test)] mod tests { - use ron::Map; - use super::*; // Test for MapCluster::subdivide() -- 2.49.1