summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--CHANGELOG.md4
-rw-r--r--examples/.gitignore2
-rw-r--r--examples/Cargo.toml3
-rw-r--r--examples/recursive-sha256/Cargo.toml10
-rw-r--r--examples/recursive-sha256/src/main.rs55
-rwxr-xr-xscript/check6
7 files changed, 81 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 96ef6c0..4fffb2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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 )
Generated by cgit. See skreutz.com for my tech blog and contact information.