diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | CHANGELOG.md | 4 | ||||
| -rw-r--r-- | examples/.gitignore | 2 | ||||
| -rw-r--r-- | examples/Cargo.toml | 3 | ||||
| -rw-r--r-- | examples/recursive-sha256/Cargo.toml | 10 | ||||
| -rw-r--r-- | examples/recursive-sha256/src/main.rs | 55 | ||||
| -rwxr-xr-x | script/check | 6 | 
7 files changed, 81 insertions, 1 deletions
| @@ -1,2 +1,2 @@  /target -Cargo.lock +/Cargo.lock diff --git a/CHANGELOG.md b/CHANGELOG.md index d324bbd..3ef36a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ The format is based on [Keep A Changelog][] and this project adheres to  ## Unreleased +### Added + +- Added recursive SHA256 example application. +  ## [0.1.0] - 2022-12-18  ### Added diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/examples/Cargo.toml b/examples/Cargo.toml new file mode 100644 index 0000000..4f10fc3 --- /dev/null +++ b/examples/Cargo.toml @@ -0,0 +1,3 @@ +[workspace] +members = ["*"] +exclude = ["target"] diff --git a/examples/recursive-sha256/Cargo.toml b/examples/recursive-sha256/Cargo.toml new file mode 100644 index 0000000..38ed665 --- /dev/null +++ b/examples/recursive-sha256/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "example-recursive-sha256" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +parseq = { path = "../.." } +sha2 = "0.10.6" +walkdir = "2.3.2" diff --git a/examples/recursive-sha256/src/main.rs b/examples/recursive-sha256/src/main.rs new file mode 100644 index 0000000..6fcbbfa --- /dev/null +++ b/examples/recursive-sha256/src/main.rs @@ -0,0 +1,55 @@ +//! Print the SHA256 sum of each regular file in the current directory recursively. + +use std::{fs::File, path::PathBuf}; + +use parseq::ParallelIterator; +use sha2::{Digest, Sha256}; +use walkdir::WalkDir; + +fn main() { +    WalkDir::new(".") +        .sort_by_file_name() +        .into_iter() +        .filter_map(|entry| match entry { +            Ok(entry) if entry.file_type().is_file() => Some(Ok(entry.into_path())), +            Ok(_) => None, +            Err(err) => Some(Err(Error::WalkdirError(err))), +        }) +        .map_parallel(|item| { +            item.and_then(|path| { +                let mut file = +                    File::open(&path).map_err(|err| Error::IoError(path.clone(), err))?; +                let mut hasher = Sha256::new(); +                std::io::copy(&mut file, &mut hasher) +                    .map_err(|err| Error::IoError(path.clone(), err))?; +                Ok((path, hasher.finalize())) +            }) +        }) +        .for_each(|item| match item { +            Ok((path, hash)) => println!("{:x} {}", hash, path.display()), +            Err(err) => eprintln!("{err}"), +        }); +} + +#[derive(Debug)] +enum Error { +    WalkdirError(walkdir::Error), +    IoError(PathBuf, std::io::Error), +} + +impl std::error::Error for Error {} + +impl std::fmt::Display for Error { +    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +        match self { +            Error::WalkdirError(err) => { +                if let Some(path) = err.path() { +                    write!(f, "{}: {}", path.display(), err) +                } else { +                    write!(f, "{err}") +                } +            } +            Error::IoError(path, err) => write!(f, "{}: {}", path.display(), err), +        } +    } +} diff --git a/script/check b/script/check index 6737278..b486aee 100755 --- a/script/check +++ b/script/check @@ -10,3 +10,9 @@ cargo test --workspace --all-targets --all-features  cargo clippy --workspace --all-targets --all-features -- --deny warnings  cargo doc --all-features --no-deps --document-private-items  cargo audit + +( cd examples && +  cargo check --workspace --all-targets --all-features && +  cargo build --workspace --all-targets --all-features && +  cargo clippy --workspace --all-targets --all-features -- --deny warnings && +  cargo audit ) |