From 4ee7111c2bcc6012e63a90d64bc5beb535ce9b83 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Thu, 26 Dec 2024 15:49:46 -0500 Subject: [PATCH] freshen up (#2) --- .github/workflows/ci.yml | 63 +++++++++++++++++++++++++++---------- Cargo.toml | 16 ++++++++-- README.md | 38 +++++++++++++++------- benches/encoder.rs | 18 ++++++----- justfile | 68 ++++++++++++++++++++++++++++++++++++++++ src/decoder.rs | 2 +- src/encoder.rs | 2 +- src/lib.rs | 3 +- 8 files changed, 168 insertions(+), 42 deletions(-) create mode 100644 justfile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed2142a..3e49160 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,25 +5,54 @@ on: branches: [ main ] pull_request: branches: [ main ] - -env: - CARGO_TERM_COLOR: always + release: + types: [ published ] + workflow_dispatch: jobs: - CI: + test: + name: Test + runs-on: ubuntu-latest + steps: + - uses: taiki-e/install-action@v2 + with: { 'tool': 'just' } + - uses: actions/checkout@v4 + - name: Ensure this crate has not yet been published (on release) + if: github.event_name == 'release' + run: just check-if-published + - uses: Swatinem/rust-cache@v2 + if: github.event_name != 'release' && github.event_name != 'workflow_dispatch' + - run: just ci-test + - name: Check semver + uses: obi1kenobi/cargo-semver-checks-action@v2 + + msrv: + name: Test MSRV runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 + - uses: taiki-e/install-action@v2 + with: { tool: just } + - uses: actions/checkout@v4 + - uses: Swatinem/rust-cache@v2 + if: github.event_name != 'release' && github.event_name != 'workflow_dispatch' + - name: Read crate metadata + id: metadata + run: echo "rust-version=$(sed -ne 's/rust-version *= *\"\(.*\)\"/\1/p' Cargo.toml)" >> $GITHUB_OUTPUT + - name: Install Rust + uses: dtolnay/rust-toolchain@stable with: - toolchain: stable - profile: default - - run: cargo fmt --all -- --check - - run: cargo build - - run: cargo test - - run: cargo clippy -- -Dwarnings - - run: cargo bench -# - name: Coveralls -# uses: coverallsapp/github-action -# with: -# github-token: ${{ secrets.GITHUB_TOKEN }} + toolchain: ${{ steps.metadata.outputs.rust-version }} + components: rustfmt + - run: just ci-test-msrv + + publish: + name: Publish to crates.io + if: startsWith(github.ref, 'refs/tags/') + needs: [ test, msrv ] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Publish to crates.io + run: cargo publish + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/Cargo.toml b/Cargo.toml index 0f8afbe..3a4c7aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,19 +1,29 @@ [package] name = "delta-encoding" version = "0.4.0" +description = "A library to encode and decode a delta-encoded stream of numbers" authors = ["Yuri Astrakhan "] +repository = "https://github.com/nyurik/delta-encoding" edition = "2021" license = "MIT OR Apache-2.0" -description = "A library to encode and decode a delta-encoded stream of numbers" -repository = "https://github.com/nyurik/delta-encoding" keywords = ["delta-encoding", "encoding", "encoder", "decoder", "protobuf"] +categories = ["encoding"] +rust-version = "1.78.0" [dependencies] num-traits = "0.2" [dev-dependencies] -criterion = { version = "0.3", features = ["html_reports"] } +criterion = { version = "0.5", features = ["html_reports"] } [[bench]] name = "encoder" harness = false + +[lints.rust] +unsafe_code = "forbid" +unused_qualifications = "warn" + +[lints.clippy] +pedantic = { level = "warn", priority = -1 } +module_name_repetitions = "allow" diff --git a/README.md b/README.md index cee22b9..6d53fbc 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,12 @@ -[![geo on Crates.io](https://img.shields.io/crates/v/delta-encoding.svg)](https://crates.io/crates/delta-encoding) -[![Coverage Status](https://coveralls.io/repos/github/nyurik/delta-encoding/badge.svg)](https://coveralls.io/github/nyurik/delta-encoding) -[![Documentation](https://docs.rs/delta-encoding/badge.svg)](https://docs.rs/delta-encoding) - # Delta-Encoding library +[![GitHub](https://img.shields.io/badge/github-nyurik/delta--encoding-8da0cb?logo=github)](https://github.com/nyurik/delta-encoding) +[![crates.io version](https://img.shields.io/crates/v/delta-encoding)](https://crates.io/crates/delta-encoding) +[![docs.rs](https://img.shields.io/docsrs/delta-encoding)](https://docs.rs/delta-encoding) +[![crates.io license](https://img.shields.io/crates/l/delta-encoding)](https://github.com/nyurik/delta-encoding/blob/main/LICENSE-APACHE) +[![CI build](https://github.com/nyurik/delta-encoding/actions/workflows/ci.yml/badge.svg)](https://github.com/nyurik/delta-encoding/actions) + + A simple library for encoding and decoding a stream of values as delta-encoded. For example, if you have a stream of values like this: ```text @@ -45,10 +48,23 @@ pub fn main() { ``` ## Development -All of these must succeed: -```bash -cargo test # Testing -cargo bench # Benchmarking -cargo fmt # Code format -cargo clippy # Code lints -``` + +* This project is easier to develop with [just](https://github.com/casey/just#readme), a modern alternative to `make`. + Install it with `cargo install just`. +* To get a list of available commands, run `just`. +* To run tests, use `just test`. + +## License + +Licensed under either of + +* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or ) +* MIT license ([LICENSE-MIT](LICENSE-MIT) or ) + at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally +submitted for inclusion in the work by you, as defined in the +Apache-2.0 license, shall be dual licensed as above, without any +additional terms or conditions. diff --git a/benches/encoder.rs b/benches/encoder.rs index eaa9273..a6ec830 100644 --- a/benches/encoder.rs +++ b/benches/encoder.rs @@ -4,11 +4,12 @@ use delta_encoding::{DeltaEncoder, DeltaEncoderExt}; criterion_group!(benches, bench_map, bench_iter); criterion_main!(benches); +#[allow(clippy::cast_possible_wrap)] fn bench_map(c: &mut Criterion) { - let samples: &[u64] = &[1, 1000, 100000]; + let samples: &[u64] = &[1, 1000, 100_000]; let mut group = c.benchmark_group("mapping"); - for count in samples.iter() { + for count in samples { group.throughput(Throughput::Bytes(*count * 8)); group.bench_function(format!("Encode {count} i64 values"), move |b| { b.iter(|| { @@ -17,25 +18,26 @@ fn bench_map(c: &mut Criterion) { .map(|v| enc.encode(v)) .for_each(|x: i64| { black_box(x); - }) - }) + }); + }); }); } group.finish(); } +#[allow(clippy::cast_possible_wrap)] fn bench_iter(c: &mut Criterion) { - let samples: &[u64] = &[1, 1000, 100000]; + let samples: &[u64] = &[1, 1000, 100_000]; let mut group = c.benchmark_group("iterator"); - for count in samples.iter() { + for count in samples { group.throughput(Throughput::Bytes(*count * 8)); group.bench_function(format!("Encode {count} i64 values"), move |b| { b.iter(|| { (0..(*count as i64)).deltas().for_each(|x: i64| { black_box(x); - }) - }) + }); + }); }); } group.finish(); diff --git a/justfile b/justfile new file mode 100644 index 0000000..3426253 --- /dev/null +++ b/justfile @@ -0,0 +1,68 @@ +#!/usr/bin/env just --justfile + +@_default: + just --list + +# Clean all build artifacts +clean: + cargo clean + rm -f Cargo.lock + +update: + cargo +nightly -Z unstable-options update --breaking + cargo update + +# Run cargo clippy +clippy: + cargo clippy --workspace --all-targets -- -D warnings + +# Test code formatting +test-fmt: + cargo fmt --all -- --check + +# Run cargo fmt +fmt: + cargo +nightly fmt -- --config imports_granularity=Module,group_imports=StdExternalCrate + +# Build and open code documentation +docs: + cargo doc --no-deps --open + +# Quick compile +check: + RUSTFLAGS='-D warnings' cargo check --workspace --all-targets + +# Run all tests +test: + RUSTFLAGS='-D warnings' cargo test --workspace --all-targets + +# Test documentation +test-doc: + cargo test --doc + RUSTDOCFLAGS="-D warnings" cargo doc --no-deps + +rust-info: + rustc --version + cargo --version + +# Run all tests as expected by CI +ci-test: rust-info test-fmt clippy check test test-doc + +# Run minimal subset of tests to ensure compatibility with MSRV +ci-test-msrv: rust-info check test + +# Verify that the current version of the crate is not the same as the one published on crates.io +check-if-published: + #!/usr/bin/env bash + LOCAL_VERSION="$(grep '^version =' Cargo.toml | sed -E 's/version = "([^"]*)".*/\1/')" + echo "Detected crate version: $LOCAL_VERSION" + CRATE_NAME="$(grep '^name =' Cargo.toml | head -1 | sed -E 's/name = "(.*)"/\1/')" + echo "Detected crate name: $CRATE_NAME" + PUBLISHED_VERSION="$(cargo search ${CRATE_NAME} | grep "^${CRATE_NAME} =" | sed -E 's/.* = "(.*)".*/\1/')" + echo "Published crate version: $PUBLISHED_VERSION" + if [ "$LOCAL_VERSION" = "$PUBLISHED_VERSION" ]; then + echo "ERROR: The current crate version has already been published." + exit 1 + else + echo "The current crate version has not yet been published." + fi diff --git a/src/decoder.rs b/src/decoder.rs index 72482c8..c956e6d 100644 --- a/src/decoder.rs +++ b/src/decoder.rs @@ -74,7 +74,7 @@ where { DeltaDecoderIter { iter: self, - decoder: Default::default(), + decoder: DeltaDecoder::default(), } } } diff --git a/src/encoder.rs b/src/encoder.rs index f959da7..4c0d0ec 100644 --- a/src/encoder.rs +++ b/src/encoder.rs @@ -76,7 +76,7 @@ where { DeltaEncoderIter { iter: self, - encoder: Default::default(), + encoder: DeltaEncoder::default(), } } } diff --git a/src/lib.rs b/src/lib.rs index 0afd1cc..d075e37 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,9 +12,10 @@ pub use decoder::{DeltaDecoder, DeltaDecoderExt, DeltaDecoderIter}; #[cfg(test)] mod tests { - use super::*; use std::iter::zip; + use super::*; + pub(crate) const TEST_DATA: &[(&[i64], &[i64])] = &[ (&[], &[]), (&[0], &[0]),