From cf92d103ebb2cdefa41178f65bf2a02195a33897 Mon Sep 17 00:00:00 2001 From: LoadingALIAS Date: Tue, 4 Nov 2025 14:02:53 -0500 Subject: [PATCH 1/4] crc-fast: wasm compatibilty fix --- .gitignore | 6 +++++- Cargo.toml | 33 ++++++++++++++++++++++++++--- src/bin/checksum.rs | 23 +++++++++++++++++--- src/lib.rs | 9 ++++++++ tests/checksum_integration_tests.rs | 22 ++++++++++++++++++- 5 files changed, 85 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index d97ced5..4e73168 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,8 @@ .idea .DS_Store .git -.vscode \ No newline at end of file +.vscode + +# personal +.claude/ +CLAUDE.md \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 7162648..2ef6d78 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,8 +24,6 @@ bench = true [dependencies] crc = "3" digest = { version = "0.10", features = ["alloc"] } -rand = "0.9" -regex = "1.12" # will be removed once Rust 1.89 is the minimum supported version rustversion = "1.0" @@ -36,6 +34,8 @@ indexmap = { version = ">=2.11.0, <2.12.0", optional = true } [dev-dependencies] criterion = "0.7" cbindgen = "0.29" +rand = "0.9" +regex = "1.12" # lto=true has a big improvement in performance [profile.release] @@ -44,11 +44,29 @@ strip = true codegen-units = 1 opt-level = 3 +[[bin]] +name = "checksum" +path = "src/bin/checksum.rs" +required-features = ["cli"] + +[[bin]] +name = "arch-check" +path = "src/bin/arch-check.rs" +required-features = ["cli"] + +[[bin]] +name = "get-custom-params" +path = "src/bin/get-custom-params.rs" +required-features = ["cli"] + [[bench]] name = "benchmark" harness = false [features] +default = ["std"] +std = [] +cli = ["std"] alloc = [] # the features below are deprecated, aren't in use, and will be removed in the next MAJOR version (v2) @@ -60,4 +78,13 @@ optimize_crc32_neon_v3s4x2e_v2 = [] # deprecated optimize_crc32_neon_blended = [] # deprecated optimize_crc32_avx512_vpclmulqdq_v3x2 = [] # deprecated optimize_crc32_avx512_v4s3x3 = [] # deprecated -optimize_crc32_sse_v4s3x3 = [] # deprecated \ No newline at end of file +optimize_crc32_sse_v4s3x3 = [] # deprecated + +[package.metadata.docs.rs] +features = ["std"] +rustdoc-args = ["--cfg", "docsrs"] + +[[test]] +name = "checksum_integration_tests" +path = "tests/checksum_integration_tests.rs" +required-features = ["cli"] \ No newline at end of file diff --git a/src/bin/checksum.rs b/src/bin/checksum.rs index 6c017bb..fad5ea5 100644 --- a/src/bin/checksum.rs +++ b/src/bin/checksum.rs @@ -3,7 +3,6 @@ //! This is a simple program to calculate a checksum from the command line use crc_fast::{checksum, checksum_file, CrcAlgorithm}; -use rand::RngCore; use std::env; use std::process::ExitCode; use std::str::FromStr; @@ -151,6 +150,21 @@ impl BenchmarkResult { } } +/// Fills a buffer with pseudo-random data using xorshift64* algorithm. +/// This is a deterministic PRNG that's tiny, fast, and suitable for benchmark data generation. +/// The seed is derived from the buffer size to provide some variability. +#[inline] +fn fill_pseudo_random(buf: &mut [u8], seed: u64) { + let mut x = seed; + for b in buf { + x ^= x >> 12; + x ^= x << 25; + x ^= x >> 27; + let r = x.wrapping_mul(0x2545_F491_4F6C_DD1D); + *b = r as u8; + } +} + fn generate_random_data(size: usize) -> Result, String> { // Check for reasonable size limits to prevent memory issues if size > 1_073_741_824 { @@ -160,8 +174,11 @@ fn generate_random_data(size: usize) -> Result, String> { // Use vec! macro to avoid clippy warning about slow initialization let mut buf = vec![0u8; size]; - let mut rng = rand::rng(); - rng.fill_bytes(&mut buf); + + // Derive seed from size for deterministic but varied data + let seed = 0x9E37_79B9_7F4A_7C15_u64.wrapping_add(size as u64); + fill_pseudo_random(&mut buf, seed); + Ok(buf) } diff --git a/src/lib.rs b/src/lib.rs index 393edb0..691d402 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,7 @@ // Copyright 2025 Don MacAskill. Licensed under MIT or Apache-2.0. +#![cfg_attr(not(feature = "std"), no_std)] + //! `crc-fast` //! =========== //! @@ -144,7 +146,10 @@ use crate::crc64::consts::{ use crate::structs::Calculator; use crate::traits::CrcCalculator; use digest::{DynDigest, InvalidBufferSize}; + +#[cfg(feature = "std")] use std::fs::File; +#[cfg(feature = "std")] use std::io::{Read, Write}; mod algorithm; @@ -545,6 +550,7 @@ impl Digest { } } +#[cfg(feature = "std")] impl Write for Digest { #[inline(always)] fn write(&mut self, buf: &[u8]) -> std::io::Result { @@ -643,6 +649,7 @@ pub fn checksum_with_params(params: CrcParams, buf: &[u8]) -> u64 { /// /// assert_eq!(checksum.unwrap(), 0xcbf43926); /// ``` +#[cfg(feature = "std")] #[inline(always)] pub fn checksum_file( algorithm: CrcAlgorithm, @@ -685,6 +692,7 @@ pub fn checksum_file( /// /// assert_eq!(checksum.unwrap(), 0xcbf43926); /// ``` +#[cfg(feature = "std")] pub fn checksum_file_with_params( params: CrcParams, path: &str, @@ -698,6 +706,7 @@ pub fn checksum_file_with_params( /// # Errors /// /// This function will return an error if the file cannot be read. +#[cfg(feature = "std")] fn checksum_file_with_digest( mut digest: Digest, path: &str, diff --git a/tests/checksum_integration_tests.rs b/tests/checksum_integration_tests.rs index 2eab8dd..b69a708 100644 --- a/tests/checksum_integration_tests.rs +++ b/tests/checksum_integration_tests.rs @@ -1,12 +1,14 @@ // Copyright 2025 Don MacAskill. Licensed under MIT or Apache-2.0. +#![cfg(feature = "cli")] + use std::fs; use std::process::Command; #[test] fn test_benchmark_flag_parsing() { let output = Command::new("cargo") - .args(&["run", "--bin", "checksum", "--", "-a", "CRC-32/ISCSI", "-b"]) + .args(&["run", "--features", "cli", "--bin", "checksum", "--", "-a", "CRC-32/ISCSI", "-b"]) .output() .expect("Failed to execute command"); @@ -25,6 +27,8 @@ fn test_benchmark_with_size_parameter() { let output = Command::new("cargo") .args(&[ "run", + "--features", + "cli", "--bin", "checksum", "--", @@ -47,6 +51,8 @@ fn test_benchmark_with_duration_parameter() { let output = Command::new("cargo") .args(&[ "run", + "--features", + "cli", "--bin", "checksum", "--", @@ -69,6 +75,8 @@ fn test_benchmark_invalid_size() { let output = Command::new("cargo") .args(&[ "run", + "--features", + "cli", "--bin", "checksum", "--", @@ -91,6 +99,8 @@ fn test_benchmark_invalid_duration() { let output = Command::new("cargo") .args(&[ "run", + "--features", + "cli", "--bin", "checksum", "--", @@ -117,6 +127,8 @@ fn test_benchmark_with_file_input() { let output = Command::new("cargo") .args(&[ "run", + "--features", + "cli", "--bin", "checksum", "--", @@ -144,6 +156,8 @@ fn test_benchmark_with_string_input() { let output = Command::new("cargo") .args(&[ "run", + "--features", + "cli", "--bin", "checksum", "--", @@ -171,6 +185,8 @@ fn test_benchmark_different_algorithms() { let output = Command::new("cargo") .args(&[ "run", + "--features", + "cli", "--bin", "checksum", "--", @@ -198,6 +214,8 @@ fn test_benchmark_size_without_benchmark_flag() { let output = Command::new("cargo") .args(&[ "run", + "--features", + "cli", "--bin", "checksum", "--", @@ -219,6 +237,8 @@ fn test_benchmark_nonexistent_file() { let output = Command::new("cargo") .args(&[ "run", + "--features", + "cli", "--bin", "checksum", "--", From 8813a60065fa95479376f311fe7a7347a6e73e4d Mon Sep 17 00:00:00 2001 From: LoadingALIAS Date: Tue, 4 Nov 2025 15:04:37 -0500 Subject: [PATCH 2/4] crc-fast-rust: updated comments for clarity && fixed tests.yaml for the updates. --- .github/workflows/tests.yml | 28 ++++++++++++++-------------- src/bin/checksum.rs | 1 + src/lib.rs | 2 +- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3b93e76..26ff789 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -25,17 +25,17 @@ jobs: components: rustfmt, clippy cache-key: ${{ matrix.os }}-${{ matrix.rust-toolchain }} - name: Check - run: cargo check + run: cargo check --all-features - name: Architecture check - run: cargo run --bin arch-check + run: cargo run --features cli --bin arch-check - if: ${{ matrix.rust-toolchain != 'nightly' }} name: Format run: cargo fmt -- --check - if: ${{ matrix.rust-toolchain != 'nightly' }} name: Clippy - run: cargo clippy + run: cargo clippy --all-features - name: Test - run: cargo test + run: cargo test --features cli test-x86_64: name: Test x86_64 @@ -56,17 +56,17 @@ jobs: components: rustfmt, clippy cache-key: ${{ matrix.os }}-${{ matrix.rust-toolchain }} - name: Check - run: cargo check + run: cargo check --all-features - name: Architecture check - run: cargo run --bin arch-check + run: cargo run --features cli --bin arch-check - if: ${{ matrix.rust-toolchain != 'nightly' }} name: Format run: cargo fmt -- --check - if: ${{ matrix.rust-toolchain != 'nightly' }} name: Clippy - run: cargo clippy + run: cargo clippy --all-features - name: Test - run: cargo test + run: cargo test --features cli test-x86: name: Test x86 @@ -88,11 +88,11 @@ jobs: - name: Set up cross run: cargo install cross --locked --version 0.2.5 - name: Check - run: cross check --target ${{ matrix.target }} + run: cross check --all-features --target ${{ matrix.target }} - name: Architecture check - run: cross run --bin arch-check --target ${{ matrix.target }} + run: cross run --features cli --bin arch-check --target ${{ matrix.target }} - name: Test - run: cross test --target ${{ matrix.target }} + run: cross test --features cli --target ${{ matrix.target }} test-software: name: Test software fallback @@ -114,8 +114,8 @@ jobs: - name: Set up cross run: cargo install cross --locked --version 0.2.5 - name: Check - run: cross check --target ${{ matrix.target }} + run: cross check --all-features --target ${{ matrix.target }} - name: Architecture check - run: cross run --bin arch-check --target ${{ matrix.target }} + run: cross run --features cli --bin arch-check --target ${{ matrix.target }} - name: Test - run: cross test --target ${{ matrix.target }} \ No newline at end of file + run: cross test --features cli --target ${{ matrix.target }} \ No newline at end of file diff --git a/src/bin/checksum.rs b/src/bin/checksum.rs index fad5ea5..962c790 100644 --- a/src/bin/checksum.rs +++ b/src/bin/checksum.rs @@ -153,6 +153,7 @@ impl BenchmarkResult { /// Fills a buffer with pseudo-random data using xorshift64* algorithm. /// This is a deterministic PRNG that's tiny, fast, and suitable for benchmark data generation. /// The seed is derived from the buffer size to provide some variability. +/// This solves the problem of having to use a full-featured PRNG like rand for benchmark data generation. #[inline] fn fill_pseudo_random(buf: &mut [u8], seed: u64) { let mut x = seed; diff --git a/src/lib.rs b/src/lib.rs index 691d402..e0f6795 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ // Copyright 2025 Don MacAskill. Licensed under MIT or Apache-2.0. - +// Future proofing for no_std support #![cfg_attr(not(feature = "std"), no_std)] //! `crc-fast` From fa8bd0f8b326487d4ddaedcd04c9436561b65716 Mon Sep 17 00:00:00 2001 From: LoadingALIAS Date: Tue, 4 Nov 2025 15:08:13 -0500 Subject: [PATCH 3/4] crc-fast-rust: fmt fix --- tests/checksum_integration_tests.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/checksum_integration_tests.rs b/tests/checksum_integration_tests.rs index b69a708..3d7e331 100644 --- a/tests/checksum_integration_tests.rs +++ b/tests/checksum_integration_tests.rs @@ -8,7 +8,17 @@ use std::process::Command; #[test] fn test_benchmark_flag_parsing() { let output = Command::new("cargo") - .args(&["run", "--features", "cli", "--bin", "checksum", "--", "-a", "CRC-32/ISCSI", "-b"]) + .args(&[ + "run", + "--features", + "cli", + "--bin", + "checksum", + "--", + "-a", + "CRC-32/ISCSI", + "-b", + ]) .output() .expect("Failed to execute command"); From ed2ede66be9464a4cca3b5d3a57b8ce8c8588a11 Mon Sep 17 00:00:00 2001 From: LoadingALIAS Date: Tue, 4 Nov 2025 15:30:53 -0500 Subject: [PATCH 4/4] crc-fast-rust: cleaning up --- .gitignore | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 4e73168..d97ced5 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,4 @@ .idea .DS_Store .git -.vscode - -# personal -.claude/ -CLAUDE.md \ No newline at end of file +.vscode \ No newline at end of file