# nidus is the workspace root AND its sole default member: `cargo build`/`cargo test`
# (and the core `just` recipes) touch ONLY nidus, keeping its pure-Rust, seconds-long
# build path intact. The benchmark crate — which pulls the heavy, FFI-laden deps nidus
# exists to avoid (bundled DuckDB C++, LanceDB/Arrow/DataFusion) — is a member built
# solely on explicit request (`-p nidus-bench`, via `just bench`).
[workspace]
members = ["benchmarks"]
default-members = ["."]

[package]
name = "nidus"
version = "0.16.0"
edition = "2024"
rust-version = "1.96"
description = "A small, pure-Rust embeddable vector store: brute-force or ANN cosine search over a single append-only directory, with pluggable persistence (local files, S3, GCS). No SQL, no query engine; builds in seconds."
repository = "https://github.com/duckedup/nidus"
license = "MIT"
keywords = ["vector", "embeddings", "search", "embedded", "database"]
categories = ["database-implementations", "data-structures"]
# Keep the published crate lean: drop issue-tracker, agent, and CI infra.
exclude = [".beads/", ".claude/", ".github/", "AGENTS.md", "justfile", "benchmarks/"]

[lib]
name = "nidus"
path = "src/lib.rs"

# The `nidus` binary: the CLI plus `nidus serve`. Gated behind the non-default
# `cli` feature (see [features]) so it builds only when asked. `cargo install
# nidus --features cli` compiles it from source; `cargo binstall nidus` fetches
# a prebuilt binary (see [package.metadata.binstall]) and needs no feature flag.
[[bin]]
name = "nidus"
path = "src/bin/nidus.rs"
required-features = ["cli"]

[features]
# Off by default — that is the whole point. With `cli` off, `cargo add nidus`
# and `cargo tree -p nidus` (`just deps`) pull NOTHING beyond the four core
# crates below, and the core build/test/Miri path stays pure and seconds-long.
# Turning it on adds the binary-only deps (all pure Rust, zero FFI).
cli = ["dep:clap", "dep:tokio", "dep:axum", "dep:tower", "dep:serde_json", "dep:tar", "dep:flate2"]

# The core is four small pure-Rust crates with no C and no FFI. The S3/GCS
# persistence backends (below) add a few more — still all pure Rust except `ring`
# (ureq's TLS, a small C+asm compile) — and they are NOT feature-gated: outgrowing
# local FS for S3 is meant to be a one-line `file://`→`s3://` runtime switch, never a
# recompile. The bar is build-and-ship SPEED (whole-crate clean build stays seconds,
# ~8× under a minute — CI asserts it), not zero-C absolutism (SPEC §1, §13.6). The
# multi-minute C trees nidus exists to avoid (bundled DuckDB C++, vendored OpenSSL,
# aws-lc-sys) stay forbidden.
[dependencies]
anyhow = "1"
serde = { version = "1", features = ["derive"] }
bincode = "1"
crc32fast = "1"

# Storage-backend deps (SPEC §13), in the DEFAULT build. The cloud clients are
# sans-IO (build + sign requests; no transport, no async) — `rusty-s3` (Sigv4 = pure
# RustCrypto HMAC) and `tame-gcs`/`tame-oauth` (GCS + OAuth2 service-account JWT) —
# executed over `ureq`, a small blocking HTTP client whose default TLS is
# rustls + `ring` (self-contained via webpki-roots; NOT aws-lc, NOT OpenSSL). `url`
# and `http` are their request types, surfaced for backend construction.
rusty-s3 = "0.9"
tame-gcs = "0.14"
tame-oauth = "0.10"
ureq = "3"
url = "2"
http = "1"

# The shared MEMORY TIER over Redis (SPEC §13.3), also in the DEFAULT build. One
# `redis-rs` blocking client covers Redis, Valkey, KeyDB, and DragonflyDB — all
# RESP-protocol-compatible — selected by `redis://`/`rediss://`/`valkey://`/… URL
# scheme. `default-features = false` keeps it SYNC (no tokio/async pulled); the
# only extra is `tls-rustls` for `rediss://`, which reuses the rustls + `ring`
# already present for ureq (NOT aws-lc, NOT a second TLS stack).
redis = { version = "1", default-features = false, features = ["tls-rustls"] }

# Binary-only deps — compiled ONLY under `--features cli`, never by library
# consumers. All pure Rust (no `*-sys`, no bundled C): clap for the CLI, and the
# tokio/axum/tower stack for `nidus serve`. `nidus serve` wraps the synchronous
# `Nidus` in `Arc<Mutex<…>>` + `spawn_blocking` — the exact async pattern the
# README/CLAUDE.md prescribe for async callers.
clap = { version = "4", features = ["derive"], optional = true }
tokio = { version = "1", features = ["rt-multi-thread", "macros", "net", "signal"], optional = true }
axum = { version = "0.8", optional = true }
tower = { version = "0.5", optional = true }
serde_json = { version = "1", optional = true }
# Backup/restore archiving. Both pure Rust, zero FFI: `tar` is std-only, and
# `flate2` is pinned to its `rust_backend` (miniz_oxide) — never a `*-sys`/C
# zlib. cli-feature-only, so the pure-`cargo add nidus` tree is untouched.
tar = { version = "0.4", optional = true }
flate2 = { version = "1", default-features = false, features = ["rust_backend"], optional = true }

[dev-dependencies]
tempfile = "3"

# Prebuilt-binary fetch for `cargo binstall nidus`. The crate is named `nidus` but
# the release assets are `nidus-<target>.tar.gz` (`.zip` on Windows), each holding
# the bare `nidus` binary at the archive root — so the URL and bin-dir are explicit.
[package.metadata.binstall]
pkg-url = "{ repo }/releases/download/v{ version }/nidus-{ target }{ archive-suffix }"
bin-dir = "nidus{ binary-ext }"
pkg-fmt = "tgz"

[package.metadata.binstall.overrides.x86_64-pc-windows-msvc]
pkg-fmt = "zip"

[profile.release]
lto = "thin"
codegen-units = 1
