diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..1d953f4 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use nix diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 26dd40b..dbcc0f0 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -1,58 +1,35 @@ on: [push, pull_request] name: build - jobs: lint: name: Format and Clippy - strategy: - matrix: - platform: [ubuntu-latest, macos-latest, windows-latest] - runs-on: ${{ matrix.platform }} - + runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v2 - + uses: actions/checkout@v4 - name: Install Rust stable toolchain - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@stable with: - profile: minimal - toolchain: stable - override: true + toolchain: 1.81.0 # We want to use a modern version of rust for better lints components: rustfmt, clippy - - name: Run cargo fmt - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - + run: cargo fmt --all -- --check - name: Run cargo clippy - uses: actions-rs/cargo@v1 - with: - command: clippy - args: --all -- -D warnings - + run: cargo clippy --all -- -D warnings test: name: Test - strategy: - matrix: - platform: [ubuntu-latest] - runs-on: ${{ matrix.platform }} - + runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v2 - + uses: actions/checkout@v4 - name: Install Rust stable toolchain uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: stable + toolchain: 1.32 # Ensure that tests past using MSRV override: true - - name: Run cargo test - uses: actions-rs/cargo@v1 - with: - command: test + run: cargo test + - name: Run cargo test for no-std + run: cargo test --no-default-feature \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index ebd3609..e1ef241 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,12 +7,17 @@ repository = "https://github.com/stusmall/murmur3" keywords = ["hash","murmur3","murmur"] license = "MIT/Apache-2.0" edition = "2018" +rust-version = "1.32" [dependencies] [dev-dependencies] murmur3-sys = { path = "./murmur3-sys"} -quickcheck = "0.9" +quickcheck = "1.0" + +[features] +default = ["std"] +std = [] [profile.bench] lto = true diff --git a/benches/bench.rs b/benches/bench.rs index 8b6e961..e777b98 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -29,7 +29,7 @@ fn bench_32_slice(b: &mut Bencher) { b.bytes = string.len() as u64; b.iter(|| { let tmp = &string[0..string.len()]; - murmur3_32_of_slice(tmp, 0); + murmur3_32_of_slice(tmp, 0) }); } diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..8db3f64 --- /dev/null +++ b/default.nix @@ -0,0 +1,33 @@ +# This is here to make a working enviroment faster and easier to set up in NixOS. The use of bindgen in rust can be +# tricky. If you don't use nixos, feel free to skip this. This project has very few deps and they are easy to set up +# on other OSes +let + rust_overlay = import (builtins.fetchTarball + # Head of master + "https://github.com/oxalica/rust-overlay/archive/36d73192555e569d27579f6c486fea3ab768823c.tar.gz" + ); + nixpkgs = import + (builtins.fetchTarball + # Head of nixos-24.05 + "https://github.com/nixos/nixpkgs/archive/944b2aea7f0a2d7c79f72468106bc5510cbf5101.tar.gz" + ) + { overlays = [ rust_overlay ]; }; + rust_toolchain = nixpkgs.rust-bin.nightly.latest.default; +in +nixpkgs.mkShell { + buildInputs = [ + rust_toolchain + nixpkgs.libclang + ]; + # Partially taken from here: https://hoverbear.org/blog/rust-bindgen-in-nix/ + shellHook = '' + export LIBCLANG_PATH=${nixpkgs.libclang.lib}/lib/ + export BINDGEN_EXTRA_CLANG_ARGS="$(< ${nixpkgs.stdenv.cc}/nix-support/libc-crt1-cflags) \ + $(< ${nixpkgs.stdenv.cc}/nix-support/libc-cflags) \ + $(< ${nixpkgs.stdenv.cc}/nix-support/cc-cflags) \ + $(< ${nixpkgs.stdenv.cc}/nix-support/libcxx-cxxflags) \ + ${nixpkgs.lib.optionalString nixpkgs.stdenv.cc.isClang "-idirafter ${nixpkgs.stdenv.cc.cc}/lib/clang/${nixpkgs.lib.getVersion nixpkgs.stdenv.cc.cc}/include"} \ + ${nixpkgs.lib.optionalString nixpkgs.stdenv.cc.isGNU "-isystem ${nixpkgs.stdenv.cc.cc}/include/c++/${nixpkgs.lib.getVersion nixpkgs.stdenv.cc.cc} -isystem ${nixpkgs.stdenv.cc.cc}/include/c++/${nixpkgs.lib.getVersion nixpkgs.stdenv.cc.cc}/${nixpkgs.stdenv.hostPlatform.config} -idirafter ${nixpkgs.stdenv.cc.cc}/lib/gcc/${nixpkgs.stdenv.hostPlatform.config}/${nixpkgs.lib.getVersion nixpkgs.stdenv.cc.cc}/include"} + " + ''; +} diff --git a/murmur3-sys/Cargo.toml b/murmur3-sys/Cargo.toml index 23c2abd..4fb3e2d 100644 --- a/murmur3-sys/Cargo.toml +++ b/murmur3-sys/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "murmur3-sys" version = "0.1.0" -authors = ["Stu Small "] +authors = ["Stu Small "] [dependencies] [build-dependencies] -bindgen = "0.53" +bindgen = "0.70" diff --git a/src/lib.rs b/src/lib.rs index 21ca76b..38ca6c1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,11 +8,16 @@ //! A pure rust implementation of the fast, non-cryptographic hash [murmur3](https://en.wikipedia.org/wiki/MurmurHash) #![deny(missing_docs)] +#![no_std] + +#[cfg(feature = "std")] +extern crate std; mod murmur3_32; mod murmur3_x64_128; mod murmur3_x86_128; +#[cfg(feature = "std")] use std::io::{ErrorKind, Read, Result}; pub use self::murmur3_32::*; @@ -33,6 +38,7 @@ where /// caused by Chain. /// /// Errors: See `std::io::Read`. +#[cfg(feature = "std")] fn read_bytes(source: &mut R, buf: &mut [u8]) -> Result where R: Read, diff --git a/src/murmur3_32.rs b/src/murmur3_32.rs index 9a97924..7932e36 100644 --- a/src/murmur3_32.rs +++ b/src/murmur3_32.rs @@ -6,9 +6,11 @@ // option. All files in the project carrying such notice may not be copied, // modified, or distributed except according to those terms. -use std::cmp::min; +use core::cmp::min; +#[cfg(feature = "std")] use std::io::{Read, Result}; +#[cfg(feature = "std")] use crate::read_bytes; const C1: u32 = 0x85eb_ca6b; @@ -26,6 +28,7 @@ const N: u32 = 0xe654_6b64; /// use murmur3::murmur3_32; /// let hash_result = murmur3_32(&mut Cursor::new("hello world"), 0); /// ``` +#[cfg(feature = "std")] pub fn murmur3_32(source: &mut T, seed: u32) -> Result { let mut buffer: [u8; 4] = [0; 4]; let mut processed = 0; diff --git a/src/murmur3_x64_128.rs b/src/murmur3_x64_128.rs index 43eca73..e57664a 100644 --- a/src/murmur3_x64_128.rs +++ b/src/murmur3_x64_128.rs @@ -6,11 +6,14 @@ // option. All files in the project carrying such notice may not be copied, // modified, or distributed except according to those terms. -use std::cmp::min; +use crate::copy_into_array; +use core::cmp::min; +use core::ops::Shl; +#[cfg(feature = "std")] use std::io::{Read, Result}; -use std::ops::Shl; -use crate::{copy_into_array, read_bytes}; +#[cfg(feature = "std")] +use crate::read_bytes; /// Use the x64 variant of the 128 bit murmur3 to hash some [Read] implementation. /// @@ -20,6 +23,7 @@ use crate::{copy_into_array, read_bytes}; /// use murmur3::murmur3_x64_128; /// let hash_result = murmur3_x64_128(&mut Cursor::new("hello world"), 0); /// ``` +#[cfg(feature = "std")] pub fn murmur3_x64_128(source: &mut T, seed: u32) -> Result { const C1: u64 = 0x87c3_7b91_1142_53d5; const C2: u64 = 0x4cf5_ad43_2745_937f; diff --git a/src/murmur3_x86_128.rs b/src/murmur3_x86_128.rs index c39fbd9..64f1517 100644 --- a/src/murmur3_x86_128.rs +++ b/src/murmur3_x86_128.rs @@ -6,11 +6,15 @@ // option. All files in the project carrying such notice may not be copied, // modified, or distributed except according to those terms. -use std::cmp::min; +use core::cmp::min; +use core::ops::Shl; +#[cfg(feature = "std")] use std::io::{Read, Result}; -use std::ops::Shl; -use crate::{copy_into_array, read_bytes}; +use crate::copy_into_array; + +#[cfg(feature = "std")] +use crate::read_bytes; /// Use the x86 variant of the 128 bit murmur3 to hash some [Read] implementation. /// @@ -20,6 +24,7 @@ use crate::{copy_into_array, read_bytes}; /// use murmur3::murmur3_x86_128; /// let hash_result = murmur3_x86_128(&mut Cursor::new("hello world"), 0); /// ``` +#[cfg(feature = "std")] pub fn murmur3_x86_128(source: &mut T, seed: u32) -> Result { const C1: u32 = 0x239b_961b; const C2: u32 = 0xab0e_9789; diff --git a/tests/quickcheck.rs b/tests/quickcheck.rs index b3a9383..4244ef1 100644 --- a/tests/quickcheck.rs +++ b/tests/quickcheck.rs @@ -11,19 +11,12 @@ extern crate quickcheck; extern crate murmur3; extern crate murmur3_sys; +#[cfg(feature = "std")] use std::io::Cursor; -use murmur3::{ - murmur3_32, murmur3_32_of_slice, murmur3_x64_128_of_slice, murmur3_x86_128_of_slice, -}; -use murmur3_sys::MurmurHash3_x86_32; - -use murmur3::murmur3_x86_128; -use murmur3_sys::MurmurHash3_x86_128; - -use murmur3::murmur3_x64_128; -use murmur3_sys::MurmurHash3_x64_128; +use murmur3_sys::{MurmurHash3_x64_128, MurmurHash3_x86_128, MurmurHash3_x86_32}; +#[cfg(feature = "std")] quickcheck! { fn quickcheck_32(input:(u32, Vec)) -> bool{ let seed = input.0; @@ -33,7 +26,7 @@ quickcheck! { MurmurHash3_x86_32(xs.as_ptr() as _, xs.len() as i32,seed,output.as_ptr() as *mut _) }; let output = u32::from_le_bytes(output); - let output2 = murmur3_32(&mut Cursor::new(xs), seed).unwrap(); + let output2 = murmur3::murmur3_32(&mut Cursor::new(xs), seed).unwrap(); output == output2 } } @@ -47,11 +40,12 @@ quickcheck! { MurmurHash3_x86_32(xs.as_ptr() as _, xs.len() as i32, seed, output.as_mut_ptr() as _) }; let output = u32::from_le_bytes(output); - let output2 = murmur3_32_of_slice(&xs[..], seed); + let output2 = murmur3::murmur3_32_of_slice(&xs[..], seed); output == output2 } } +#[cfg(feature = "std")] quickcheck! { fn quickcheck_x86_128(input:(u32, Vec)) -> bool { let seed = input.0; @@ -61,7 +55,7 @@ quickcheck! { MurmurHash3_x86_128(xs.as_ptr() as _, xs.len() as i32,seed,output_bytes.as_ptr() as *mut _) }; let output = u128::from_le_bytes(output_bytes); - let output2 = murmur3_x86_128(&mut Cursor::new(xs), seed).unwrap(); + let output2 = murmur3::murmur3_x86_128(&mut Cursor::new(xs), seed).unwrap(); output == output2 } } @@ -75,7 +69,22 @@ quickcheck! { MurmurHash3_x86_128(xs.as_ptr() as _, xs.len() as i32,seed,output_bytes.as_ptr() as *mut _) }; let output = u128::from_le_bytes(output_bytes); - let output2 = murmur3_x86_128_of_slice(&xs, seed); + let output2 = murmur3::murmur3_x86_128_of_slice(&xs, seed); + output == output2 + } +} + +#[cfg(feature = "std")] +quickcheck! { + fn quickcheck_x64_128(input:(u32, Vec)) -> bool { + let seed = input.0; + let xs = input.1; + let output_bytes: [u8; 16] = [0; 16]; + unsafe { + MurmurHash3_x64_128(xs.as_ptr() as _, xs.len() as i32,seed,output_bytes.as_ptr() as *mut _) + }; + let output = u128::from_le_bytes(output_bytes); + let output2 = murmur3::murmur3_x64_128(&mut Cursor::new(xs), seed).unwrap(); output == output2 } } @@ -89,7 +98,7 @@ quickcheck! { MurmurHash3_x64_128(xs.as_ptr() as _, xs.len() as i32,seed, output_bytes.as_ptr() as *mut _) }; let output = u128::from_le_bytes(output_bytes); - let output2 = murmur3_x64_128_of_slice(&xs, seed); + let output2 = murmur3::murmur3_x64_128_of_slice(&xs, seed); output == output2 } } diff --git a/tests/test.rs b/tests/test.rs index 6596fbf..d9b9212 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -5,7 +5,7 @@ // license , at your // option. All files in the project carrying such notice may not be copied, // modified, or distributed except according to those terms. - +#![cfg(feature = "std")] extern crate murmur3; use std::io::{Cursor, Read};