{
description = "Durable bounded queue with zstd+CBOR segment files, ack-based deletion, and crash recovery";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
systems.url = "github:nix-systems/default";
treefmt-nix = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
crane.url = "github:ipetkov/crane";
# rust-overlay gives us pinned MSRV (1.85) and nightly toolchains
# alongside whatever nixpkgs' default stable happens to be.
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
inputs@{ self, flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
systems = import inputs.systems;
imports = [ inputs.treefmt-nix.flakeModule ];
perSystem =
{
config,
pkgs,
lib,
...
}:
let
# Extend pkgs with rust-bin from rust-overlay so we can pull pinned
# MSRV and nightly toolchains without changing default behavior.
# `inputs` is available via closure (flake-parts injects it).
pkgsRust = pkgs.extend (import inputs.rust-overlay);
craneLib = inputs.crane.mkLib pkgs;
# MSRV-pinned crane: proves `packages.default` builds on the crate's
# declared floor (1.85), not just on whatever nixpkgs stable ships.
# The checks (test/clippy/doc) keep using `craneLib` (stable) for
# broader coverage; only the shipped package is MSRV-locked.
craneLibMsrv = (inputs.crane.mkLib pkgsRust).overrideToolchain (
p: p.rust-bin.stable."1.85.0".minimal
);
# Source filtered to Cargo-relevant files for build caching.
src = craneLib.cleanCargoSource ./.;
# zstd-sys compiles bundled libzstd from C (needs a C compiler, which
# stdenv provides in builds); system zstd + pkg-config cover the
# optional system-lib path used by some zstd-sys configurations.
commonArgs = {
inherit src;
nativeBuildInputs = [ pkgs.pkg-config ];
buildInputs = [ pkgs.zstd ];
strictDeps = true;
};
# Build dependencies once (with the encryption feature so aes-gcm and
# rand are vendored), then reuse the artifacts across every check.
cargoArtifacts = craneLib.buildDepsOnly (
commonArgs
// {
cargoExtraArgs = "--features encryption";
}
);
# Dependency artifacts built under the MSRV toolchain, reused by
# `packages.default` so it does not rebuild deps from scratch.
cargoArtifactsMsrv = craneLibMsrv.buildDepsOnly (
commonArgs
// {
cargoExtraArgs = "--features encryption";
}
);
in
{
# Reproducible dev shell. mkShell (not mkShellNoCC) because zstd-sys
# compiles bundled C and needs a C compiler from stdenv.
devShells.default = pkgs.mkShell {
packages = with pkgs; [
rustc
cargo
rustfmt
clippy
rust-analyzer
zstd
pkg-config
];
};
# Minimal CI shell: just the toolchain.
devShells.ci = pkgs.mkShell {
packages = with pkgs; [
rustc
cargo
rustfmt
clippy
];
};
# MSRV verification shell — pinned Rust 1.85 (the floor declared in
# Cargo.toml's `rust-version`). Use this to validate that the crate
# actually compiles on its declared MSRV:
#
# nix develop .#msrv -c cargo check --all-targets --features encryption
#
# (Note: `cargo +1.85.0` syntax is rustup-only and does NOT work
# inside a Nix shell — use the shell's cargo directly.)
devShells.msrv = pkgs.mkShell {
packages = [
pkgsRust.rust-bin.stable."1.85.0".default
pkgs.pkg-config
pkgs.zstd
];
};
# Fuzz shell — nightly Rust for libfuzzer-sys / `cargo +nightly fuzz`.
# Use this to actually run the fuzz targets:
#
# nix develop .#fuzz -c cargo fuzz run fuzz_corrupted_read -- -max_total_time=60
devShells.fuzz = pkgs.mkShell {
packages = [
(pkgsRust.rust-bin.nightly.latest.minimal.override {
extensions = [
"rust-src"
"rustc-codegen-cranelift"
"rustc-dev"
];
})
pkgs.pkg-config
pkgs.zstd
];
};
packages.default = craneLibMsrv.buildPackage (
commonArgs
// {
cargoArtifacts = cargoArtifactsMsrv;
cargoExtraArgs = "--features encryption";
doCheck = false;
meta = with lib; {
description = "Durable bounded queue with zstd+CBOR segment files";
license = licenses.asl20;
};
}
);
checks = {
build = config.packages.default;
test = craneLib.cargoTest (
commonArgs
// {
inherit cargoArtifacts;
cargoExtraArgs = "--features encryption";
cargoTestExtraArgs = "--no-fail-fast";
}
);
clippy = craneLib.cargoClippy (
commonArgs
// {
inherit cargoArtifacts;
cargoExtraArgs = "--all-targets --features encryption";
cargoClippyExtraArgs = "-- -D warnings";
}
);
fmt = craneLib.cargoFmt { src = ./.; };
doc = craneLib.cargoDoc (
commonArgs
// {
inherit cargoArtifacts;
cargoExtraArgs = "--no-deps --features encryption";
}
);
};
treefmt = {
projectRootFile = "Cargo.toml";
programs = {
nixfmt.enable = true;
rustfmt = {
enable = true;
# Match the crate's edition so `nix fmt` agrees with `cargo fmt`.
edition = "2021";
};
};
};
# Reproducible fuzz runners. Each app runs one cargo-fuzz target
# under the pinned nightly toolchain for `seconds` (default 60).
# Override via:
# nix run .#fuzz-corrupted-read -- 300
# nix run .#fuzz-recovery -- --max-len=4096
apps =
let
mkFuzzApp = target: {
type = "app";
program = pkgs.writeShellScriptBin "fuzz-${target}" ''
set -euo pipefail
export PATH="${
pkgs.lib.makeBinPath [
(pkgsRust.rust-bin.nightly.latest.minimal.override {
extensions = [ "rust-src" ];
})
pkgs.cargo
]
}:$PATH"
export LD_LIBRARY_PATH="${
pkgs.lib.makeLibraryPath [ pkgs.zstd ]
}''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
# cargo-fuzz needs to be on PATH; expect the caller to have
# installed it once via `cargo install cargo-fuzz`.
export PATH="$HOME/.cargo/bin:$PATH"
cd "$PWD"
exec cargo-fuzz run ${target} -- -max_total_time="''${1:-60}" "''${@:2}"
'';
};
in
{
fuzz-corrupted-read = mkFuzzApp "fuzz_corrupted_read";
fuzz-recovery = mkFuzzApp "fuzz_recovery";
};
};
};
}