From bfcf9066b939ad2cd52109031699f727f64c53e6 Mon Sep 17 00:00:00 2001 From: GordonYuanyc Date: Thu, 14 May 2026 07:26:26 +0000 Subject: [PATCH 1/2] refactor(build): vendor prost output, drop build.rs Move `.proto` -> Rust code generation from a per-build build script to a maintainer-only tool at `tools/gen-proto/`. The generated file is now checked in at `src/proto/generated/sketchlib.v1.rs`, so the published crate is pure Rust: - downstream `cargo build` no longer compiles `prost-build`, `protoc-bin-vendored`, or any of their ~30 transitive deps; - no `protoc` is required at build time; - `[build-dependencies]` is now empty; - `Cargo.lock` shrinks by ~280 lines. Maintainers regenerate after editing any `proto/**/*.proto` with: cargo run --manifest-path tools/gen-proto/Cargo.toml A new CI job `proto-vendored-up-to-date` runs the generator and rejects any pull request whose committed `src/proto/generated/` does not match the result. The `cross_language_proto` integration test continues to pass, confirming the vendored types are byte-equivalent to the previous build-time output. Co-authored-by: Cursor --- .github/workflows/ci.yml | 28 ++ .github/workflows/docs.yml | 4 +- Cargo.lock | 280 ------------ Cargo.toml | 7 +- README.md | 38 +- build.rs | 32 -- docs/library_map.md | 16 + src/proto.rs | 17 +- src/proto/generated/sketchlib.v1.rs | 652 ++++++++++++++++++++++++++++ tools/gen-proto/Cargo.toml | 15 + tools/gen-proto/src/main.rs | 94 ++++ 11 files changed, 842 insertions(+), 341 deletions(-) delete mode 100644 build.rs create mode 100644 src/proto/generated/sketchlib.v1.rs create mode 100644 tools/gen-proto/Cargo.toml create mode 100644 tools/gen-proto/src/main.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c854a5b..dcbde2b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,3 +37,31 @@ jobs: - name: Run tests run: cargo test --all-features --locked --verbose + + proto-vendored-up-to-date: + name: Vendored proto code is up to date + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Rust + uses: dtolnay/rust-toolchain@stable + + - name: Cache Cargo dependencies and build artifacts + uses: Swatinem/rust-cache@v2 + with: + workspaces: tools/gen-proto -> tools/gen-proto/target + + - name: Regenerate vendored proto code + run: cargo run --manifest-path tools/gen-proto/Cargo.toml --locked + + - name: Verify src/proto/generated/ has no drift + run: | + if ! git diff --exit-code -- src/proto/generated; then + echo "::error::src/proto/generated/ is out of date. Run:" >&2 + echo " cargo run --manifest-path tools/gen-proto/Cargo.toml" >&2 + echo "and commit the result." >&2 + exit 1 + fi diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index af49398..3458961 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -6,7 +6,7 @@ on: paths: - "src/**" - "proto/**" - - "build.rs" + - "tools/gen-proto/**" - "Cargo.toml" - "Cargo.lock" - "README.md" @@ -17,7 +17,7 @@ on: paths: - "src/**" - "proto/**" - - "build.rs" + - "tools/gen-proto/**" - "Cargo.toml" - "Cargo.lock" - "README.md" diff --git a/Cargo.lock b/Cargo.lock index 4775a84..64f3e45 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - [[package]] name = "anyhow" version = "1.0.102" @@ -25,8 +16,6 @@ dependencies = [ "core_affinity", "crossbeam-channel", "prost", - "prost-build", - "protoc-bin-vendored", "rand", "rmp-serde", "serde", @@ -42,12 +31,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "bitflags" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" - [[package]] name = "byteorder" version = "1.5.0" @@ -98,34 +81,6 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" - [[package]] name = "getrandom" version = "0.3.3" @@ -138,34 +93,12 @@ dependencies = [ "wasi", ] -[[package]] -name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - [[package]] name = "hermit-abi" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" -[[package]] -name = "indexmap" -version = "2.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" -dependencies = [ - "equivalent", - "hashbrown", -] - [[package]] name = "itertools" version = "0.10.5" @@ -181,30 +114,6 @@ version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" - -[[package]] -name = "log" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" - -[[package]] -name = "memchr" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" - -[[package]] -name = "multimap" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" - [[package]] name = "num-traits" version = "0.2.19" @@ -224,28 +133,12 @@ dependencies = [ "libc", ] -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - [[package]] name = "paste" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "petgraph" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" -dependencies = [ - "fixedbitset", - "indexmap", -] - [[package]] name = "ppv-lite86" version = "0.2.21" @@ -255,16 +148,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "proc-macro2" version = "1.0.101" @@ -284,26 +167,6 @@ dependencies = [ "prost-derive", ] -[[package]] -name = "prost-build" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" -dependencies = [ - "heck", - "itertools", - "log", - "multimap", - "once_cell", - "petgraph", - "prettyplease", - "prost", - "prost-types", - "regex", - "syn", - "tempfile", -] - [[package]] name = "prost-derive" version = "0.13.5" @@ -317,79 +180,6 @@ dependencies = [ "syn", ] -[[package]] -name = "prost-types" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" -dependencies = [ - "prost", -] - -[[package]] -name = "protoc-bin-vendored" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1c381df33c98266b5f08186583660090a4ffa0889e76c7e9a5e175f645a67fa" -dependencies = [ - "protoc-bin-vendored-linux-aarch_64", - "protoc-bin-vendored-linux-ppcle_64", - "protoc-bin-vendored-linux-s390_64", - "protoc-bin-vendored-linux-x86_32", - "protoc-bin-vendored-linux-x86_64", - "protoc-bin-vendored-macos-aarch_64", - "protoc-bin-vendored-macos-x86_64", - "protoc-bin-vendored-win32", -] - -[[package]] -name = "protoc-bin-vendored-linux-aarch_64" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c350df4d49b5b9e3ca79f7e646fde2377b199e13cfa87320308397e1f37e1a4c" - -[[package]] -name = "protoc-bin-vendored-linux-ppcle_64" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55a63e6c7244f19b5c6393f025017eb5d793fd5467823a099740a7a4222440c" - -[[package]] -name = "protoc-bin-vendored-linux-s390_64" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dba5565db4288e935d5330a07c264a4ee8e4a5b4a4e6f4e83fad824cc32f3b0" - -[[package]] -name = "protoc-bin-vendored-linux-x86_32" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8854774b24ee28b7868cd71dccaae8e02a2365e67a4a87a6cd11ee6cdbdf9cf5" - -[[package]] -name = "protoc-bin-vendored-linux-x86_64" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b38b07546580df720fa464ce124c4b03630a6fb83e05c336fea2a241df7e5d78" - -[[package]] -name = "protoc-bin-vendored-macos-aarch_64" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89278a9926ce312e51f1d999fee8825d324d603213344a9a706daa009f1d8092" - -[[package]] -name = "protoc-bin-vendored-macos-x86_64" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81745feda7ccfb9471d7a4de888f0652e806d5795b61480605d4943176299756" - -[[package]] -name = "protoc-bin-vendored-win32" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95067976aca6421a523e491fce939a3e65249bac4b977adee0ee9771568e8aa3" - [[package]] name = "quote" version = "1.0.41" @@ -434,35 +224,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "regex" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a52d8d02cacdb176ef4678de6c052efb4b3da14b78e4db683a4252762be5433" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "722166aa0d7438abbaa4d5cc2c649dac844e8c56d82fb3d33e9c34b5cd268fc6" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3160422bbd54dd5ecfdca71e5fd59b7b8fe2b1697ab2baf64f6d05dcc66d298" - [[package]] name = "rmp" version = "0.8.14" @@ -485,19 +246,6 @@ dependencies = [ "serde", ] -[[package]] -name = "rustix" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - [[package]] name = "serde" version = "1.0.228" @@ -554,19 +302,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tempfile" -version = "3.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" -dependencies = [ - "fastrand", - "getrandom", - "once_cell", - "rustix", - "windows-sys", -] - [[package]] name = "twox-hash" version = "2.1.2" @@ -622,21 +357,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - [[package]] name = "wit-bindgen" version = "0.46.0" diff --git a/Cargo.toml b/Cargo.toml index 56c5284..a7376cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,9 +34,10 @@ default = [] experimental = [] octo-runtime = ["core_affinity", "crossbeam-channel"] -[build-dependencies] -prost-build = "0.13" -protoc-bin-vendored = "3" +# Note: there are intentionally no `[build-dependencies]`. The prost output +# under `src/proto/generated/` is checked in and refreshed by the maintainer +# tool at `tools/gen-proto/`. This keeps the published crate pure-Rust with +# no requirement on `protoc` for downstream consumers. [lib] crate-type = ["rlib"] diff --git a/README.md b/README.md index 243f953..72d7e83 100644 --- a/README.md +++ b/README.md @@ -185,36 +185,30 @@ cargo build --features experimental cargo test --features "experimental octo-runtime" ``` -## Protobuf Requirements +## Protobuf code generation -This project compiles `.proto` files at build time via `prost-build` in `build.rs`. -The required Protocol Buffers compiler (`protoc`) is provided through the vendored -`protoc-bin-vendored` build dependency, so a separate system installation is usually -not needed on common development platforms. +`asap_sketchlib` is a pure-Rust crate: building it does **not** require +`protoc` or any build script. The Rust types generated from +`proto/**/*.proto` are vendored into `src/proto/generated/` and refreshed +manually by maintainers using the in-repo tool at `tools/gen-proto/`. -If you prefer to use a system-installed compiler instead, that works too. Install -`protoc` with your platform package manager: +Downstream users can therefore simply add the crate to their `Cargo.toml` and +build it like any other pure-Rust dependency. -```bash -# macOS (Homebrew) -brew install protobuf - -# Ubuntu / Debian -sudo apt-get update && sudo apt-get install -y protobuf-compiler - -# Windows (Chocolatey) -choco install protoc -``` +### For maintainers -Verify installation: +After editing any `.proto` file, regenerate the vendored output and commit +the result: ```bash -protoc --version +cargo run --manifest-path tools/gen-proto/Cargo.toml +git add src/proto/generated ``` -If you need to override the compiler for a custom environment, set the `PROTOC` -environment variable to the path of your preferred `protoc` binary before running -`cargo build` or `cargo test`. +The tool uses `prost-build` together with the `protoc-bin-vendored` binary, +so no system `protoc` is required to regenerate either. CI rejects any pull +request whose committed `src/proto/generated/` does not match the result of +running this command on its current `.proto` sources. ## FAQ diff --git a/build.rs b/build.rs deleted file mode 100644 index 9347437..0000000 --- a/build.rs +++ /dev/null @@ -1,32 +0,0 @@ -//! Build script that compiles the crate's protobuf definitions. -//! -//! The large precomputed sampling and hash tables that used to live next to -//! this file as multi-megabyte literal arrays are now built lazily at runtime -//! via [`std::sync::LazyLock`] (see `src/common/precompute_*.rs`), so this -//! script no longer needs to do any code generation beyond `prost`. - -fn main() { - let protoc = - protoc_bin_vendored::protoc_bin_path().expect("failed to locate vendored protoc binary"); - unsafe { - std::env::set_var("PROTOC", protoc); - } - - prost_build::compile_protos( - &[ - "proto/common/common.proto", - "proto/countminsketch/countminsketch.proto", - "proto/countsketch/countsketch.proto", - "proto/hll/hll.proto", - "proto/kll/kll.proto", - "proto/ddsketch/ddsketch.proto", - "proto/univmon/univmon.proto", - "proto/hydra/hydra.proto", - "proto/cocosketch/cocosketch.proto", - "proto/elasticsketch/elasticsketch.proto", - "proto/sketchlib.proto", - ], - &["proto"], - ) - .expect("prost_build failed to compile proto files"); -} diff --git a/docs/library_map.md b/docs/library_map.md index 8ba5503..978c61c 100644 --- a/docs/library_map.md +++ b/docs/library_map.md @@ -35,3 +35,19 @@ they are built lazily at runtime via `std::sync::LazyLock` in `src/common/precompute_hash.rs`, `src/common/precompute_sample.rs`, and `src/common/precompute_sample2.rs`. + +## Proto code generation + +- `proto/**/*.proto` is the cross-language wire-format source of truth shared + with `sketchlib-go`. +- The corresponding Rust types are **vendored** under + `src/proto/generated/sketchlib.v1.rs` and re-exported by `src/proto.rs` as + `crate::proto::sketchlib`. Downstream users therefore build the crate as + pure Rust without needing `protoc` or any build script. +- To regenerate after editing any `.proto` file, run from the repository root: + + ```bash + cargo run --manifest-path tools/gen-proto/Cargo.toml + ``` + + CI enforces that the committed file matches the result of regeneration. diff --git a/src/proto.rs b/src/proto.rs index bbbb10a..933fe26 100644 --- a/src/proto.rs +++ b/src/proto.rs @@ -1,7 +1,20 @@ // Proto-generated types for cross-language sketch serialization. -// Generated by prost-build from proto/sketchlib.proto at build time. +// +// The contents of `sketchlib` are vendored: the file under +// `src/proto/generated/sketchlib.v1.rs` is produced by `tools/gen-proto` +// and committed to the repository. End-users of this crate therefore do +// not need `protoc` or any build-script machinery to build it. +// +// To regenerate after editing any `proto/**/*.proto`: +// +// cargo run --manifest-path tools/gen-proto/Cargo.toml +// +// CI enforces that the committed file matches the result of running the +// tool against the current `.proto` sources. #[allow(rustdoc::broken_intra_doc_links)] #[allow(missing_docs)] +#[allow(clippy::all)] +#[rustfmt::skip] pub mod sketchlib { - include!(concat!(env!("OUT_DIR"), "/sketchlib.v1.rs")); + include!("proto/generated/sketchlib.v1.rs"); } diff --git a/src/proto/generated/sketchlib.v1.rs b/src/proto/generated/sketchlib.v1.rs new file mode 100644 index 0000000..04b74e1 --- /dev/null +++ b/src/proto/generated/sketchlib.v1.rs @@ -0,0 +1,652 @@ +// @generated by tools/gen-proto -- DO NOT EDIT. +// +// Regenerate with: +// cargo run --manifest-path tools/gen-proto/Cargo.toml +// +// Source of truth: proto/**/*.proto + +// This file is @generated by prost-build. +/// ProducerInfo records which library version created this envelope. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProducerInfo { + /// One of "sketchlib-go" or "asap_sketchlib". + #[prost(string, tag = "1")] + pub library: ::prost::alloc::string::String, + /// Semantic version string of the producing library, e.g. "0.1.0". + #[prost(string, tag = "2")] + pub version: ::prost::alloc::string::String, +} +/// HashSpec fully describes the hashing configuration so both sides can confirm +/// they will compute identical bucket indices. +/// +/// Both libraries share: +/// canonical_seed_index = 5 (CanonicalHashSeed / CANONICAL_HASH_SEED) +/// seed_list = the 20-entry table in hash.go / hash.rs +/// seed_derivation = ADDITIVE_OFFSET for per-row seeds +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct HashSpec { + /// Hash algorithm used for all sketch operations. + #[prost(enumeration = "HashAlgorithm", tag = "1")] + pub algorithm: i32, + /// Index into seed_list used as the primary (canonical) hash seed. + /// Both libraries default to 5. + #[prost(uint32, tag = "2")] + pub canonical_seed_index: u32, + /// Complete seed table. Must be identical on both sides for correct results. + /// Both libraries currently use exactly 20 seeds; producers always emit all 20. + #[prost(uint64, repeated, tag = "3")] + pub seed_list: ::prost::alloc::vec::Vec, + /// How per-row seeds are derived from the base seed index. + #[prost(enumeration = "SeedDerivation", tag = "4")] + pub seed_derivation: i32, +} +/// HashAlgorithm enumerates supported hash algorithms. +/// Only XXH3_64 is cross-language stable for the current implementation. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum HashAlgorithm { + Unspecified = 0, + /// xxHash3 64-bit with seed (zeebo/xxh3 in Go; twox-hash XxHash3_64 in Rust). + /// This is the standard algorithm for both libraries. + Xxh364 = 1, + /// xxHash3 128-bit with seed. Used for HLL register indexing and packed matrix + /// hashes that exceed 64 bits. + Xxh3128 = 2, + /// xxHash 64-bit (non-XXH3). Reserved for legacy data; not produced by either + /// current library. + Xxhash64 = 3, +} +impl HashAlgorithm { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "HASH_ALGORITHM_UNSPECIFIED", + Self::Xxh364 => "HASH_ALGORITHM_XXH3_64", + Self::Xxh3128 => "HASH_ALGORITHM_XXH3_128", + Self::Xxhash64 => "HASH_ALGORITHM_XXHASH64", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "HASH_ALGORITHM_UNSPECIFIED" => Some(Self::Unspecified), + "HASH_ALGORITHM_XXH3_64" => Some(Self::Xxh364), + "HASH_ALGORITHM_XXH3_128" => Some(Self::Xxh3128), + "HASH_ALGORITHM_XXHASH64" => Some(Self::Xxhash64), + _ => None, + } + } +} +/// SeedDerivation describes how per-row seed indices are produced. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum SeedDerivation { + Unspecified = 0, + /// Each row r uses seed_list\[(base + r) % len(seed_list)\]. + /// Standard derivation for multi-row sketches (CountMin, CountSketch). + AdditiveOffset = 1, + /// All rows share a single hash (Packed64 or Packed128 fast-path). + /// Applicable only when the total bit-width fits in 64 or 128 bits. + Packed = 2, +} +impl SeedDerivation { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "SEED_DERIVATION_UNSPECIFIED", + Self::AdditiveOffset => "SEED_DERIVATION_ADDITIVE_OFFSET", + Self::Packed => "SEED_DERIVATION_PACKED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "SEED_DERIVATION_UNSPECIFIED" => Some(Self::Unspecified), + "SEED_DERIVATION_ADDITIVE_OFFSET" => Some(Self::AdditiveOffset), + "SEED_DERIVATION_PACKED" => Some(Self::Packed), + _ => None, + } + } +} +/// CounterType identifies the numeric type used to store matrix counters. +/// Go defaults to FLOAT64; Rust defaults to INT32. +/// Determines which counts_* array is populated in CountMinState and +/// CountSketchState. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum CounterType { + Unspecified = 0, + /// Rust default for CountMin / CountSketch. + Int32 = 1, + Int64 = 2, + /// INT128 is stored as pairs of int64 (hi, lo) interleaved in counts_int. + Int128 = 3, + /// Go default for CountMin / CountSketch. + Float64 = 4, +} +impl CounterType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "COUNTER_TYPE_UNSPECIFIED", + Self::Int32 => "COUNTER_TYPE_INT32", + Self::Int64 => "COUNTER_TYPE_INT64", + Self::Int128 => "COUNTER_TYPE_INT128", + Self::Float64 => "COUNTER_TYPE_FLOAT64", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "COUNTER_TYPE_UNSPECIFIED" => Some(Self::Unspecified), + "COUNTER_TYPE_INT32" => Some(Self::Int32), + "COUNTER_TYPE_INT64" => Some(Self::Int64), + "COUNTER_TYPE_INT128" => Some(Self::Int128), + "COUNTER_TYPE_FLOAT64" => Some(Self::Float64), + _ => None, + } + } +} +/// CountMinState is the portable state of a Count-Min Sketch. +/// +/// The counter matrix is stored flat in row-major order: +/// element [r][c] is at index r * cols + c. +/// +/// The Go implementation tracks auxiliary sum/L1/L2 arrays that the Rust +/// implementation does not produce. These fields are optional; consumers +/// that need them must recompute from raw insertions if absent. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CountMinState { + /// Matrix dimensions. Both must be > 0. + #[prost(uint32, tag = "1")] + pub rows: u32, + #[prost(uint32, tag = "2")] + pub cols: u32, + /// Indicates which counts_* field below is populated. + #[prost(enumeration = "CounterType", tag = "3")] + pub counter_type: i32, + /// Integer counters in row-major order, length = rows * cols. + /// Populated when counter_type ∈ {INT32, INT64}. + /// Use sint64 for efficient varint encoding of near-zero values. + /// For INT128 counters, values are interleaved as (hi_i, lo_i) pairs, + /// making the effective length 2 * rows * cols. + #[prost(sint64, repeated, tag = "4")] + pub counts_int: ::prost::alloc::vec::Vec, + /// Floating-point counters in row-major order, length = rows * cols. + /// Populated when counter_type = FLOAT64 (Go producer). + #[prost(double, repeated, tag = "5")] + pub counts_float: ::prost::alloc::vec::Vec, + /// Sum-weighted counter matrix (same layout as counts_*), length = rows * cols. + #[prost(double, repeated, tag = "6")] + pub sum_counts: ::prost::alloc::vec::Vec, + /// Sum-of-squares counter matrix, length = rows * cols. + #[prost(double, repeated, tag = "7")] + pub sum2_counts: ::prost::alloc::vec::Vec, + /// Per-row L1 norms, length = rows. + #[prost(double, repeated, tag = "8")] + pub l1: ::prost::alloc::vec::Vec, + /// Per-row L2 norms, length = rows. Recompute if absent. + #[prost(double, repeated, tag = "9")] + pub l2: ::prost::alloc::vec::Vec, +} +/// CountSketchState is the portable state of a Count (±1) Sketch. +/// +/// The counter matrix is signed because Count Sketch uses ±1 increments. +/// The matrix layout is identical to CountMinState (row-major, flat). +/// +/// L2 norms are derived values and must be recomputed on load: +/// l2\[r\] = sqrt( sum_c counts[r][c]^2 ) +/// Producers may include them as a convenience for consumers that only query. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CountSketchState { + /// Matrix dimensions. Both must be > 0. + #[prost(uint32, tag = "1")] + pub rows: u32, + #[prost(uint32, tag = "2")] + pub cols: u32, + /// Indicates which counts_* field below is populated. + #[prost(enumeration = "CounterType", tag = "3")] + pub counter_type: i32, + /// Signed integer counters in row-major order, length = rows * cols. + /// Populated when counter_type ∈ {INT32, INT64}. + #[prost(sint64, repeated, tag = "4")] + pub counts_int: ::prost::alloc::vec::Vec, + /// Floating-point counters in row-major order, length = rows * cols. + /// Populated when counter_type = FLOAT64 (Go producer). + #[prost(double, repeated, tag = "5")] + pub counts_float: ::prost::alloc::vec::Vec, + /// Per-row L2 norms, length = rows. Derived — recompute on load if absent. + #[prost(double, repeated, tag = "6")] + pub l2: ::prost::alloc::vec::Vec, + /// Optional heavy-hitter (TopK min-heap) state. + /// Absent when TopK tracking is disabled. + #[prost(message, optional, tag = "7")] + pub topk: ::core::option::Option, +} +/// TopKState is the serialized state of a min-heap heavy-hitter tracker. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TopKState { + /// Maximum number of entries retained. + #[prost(uint32, tag = "1")] + pub k: u32, + /// All retained entries. Order is not guaranteed (heap order is not preserved). + #[prost(message, repeated, tag = "2")] + pub entries: ::prost::alloc::vec::Vec, +} +/// HeapEntry is one heavy-hitter record inside a TopKState. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct HeapEntry { + /// String key identifying the heavy hitter (e.g. flow ID, IP address). + /// For binary keys, producers should use base64 or hex encoding and document + /// their choice; a future bytes_key field is reserved at number 3. + #[prost(string, tag = "1")] + pub key: ::prost::alloc::string::String, + /// Approximate frequency or weight accumulated for this key. + #[prost(double, tag = "2")] + pub count: f64, +} +/// HyperLogLogState is the portable state of a HyperLogLog cardinality sketch. +/// +/// Precision p determines the register count: num_registers = 2^precision. +/// Both libraries default to precision = 14 (16 384 registers). +/// +/// The variant field is required because the three estimator algorithms are +/// not interchangeable: loading an ErtlMLE state into a Regular estimator +/// (or vice versa) produces incorrect cardinality estimates. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct HyperLogLogState { + /// HLL estimator variant. Required. + #[prost(enumeration = "HllVariant", tag = "1")] + pub variant: i32, + /// Log₂ of the number of registers (precision parameter p). + /// Default = 14 → 16 384 registers. + #[prost(uint32, tag = "2")] + pub precision: u32, + /// Raw register values, length = 2^precision. + /// Each byte stores the maximum (leading-zeros + 1) seen for that bucket. + /// Stored as a raw byte string for compact encoding (1 byte per register). + #[prost(bytes = "vec", tag = "3")] + pub registers: ::prost::alloc::vec::Vec, + /// HIP accumulator component kxq0. + #[prost(double, tag = "4")] + pub hip_kxq0: f64, + /// HIP accumulator component kxq1. + #[prost(double, tag = "5")] + pub hip_kxq1: f64, + /// HIP running cardinality estimate. + #[prost(double, tag = "6")] + pub hip_est: f64, +} +/// HLLVariant identifies which HLL estimator algorithm the registers belong to. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum HllVariant { + Unspecified = 0, + /// Classic HLL with bias-correction tables (Flajolet et al. 2007). + Regular = 1, + /// Otmar Ertl's MLE estimator (arXiv:1702.01284). + /// Originally derived from Apache DataFusion's HLL implementation. + /// Not compatible with REGULAR registers. + ErtlMle = 2, + /// Kevin Lang's HyperLogLog++ Improved Proposal (HIP). + /// Requires hip_kxq0, hip_kxq1, hip_est to be populated. + Hip = 3, +} +impl HllVariant { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "HLL_VARIANT_UNSPECIFIED", + Self::Regular => "HLL_VARIANT_REGULAR", + Self::ErtlMle => "HLL_VARIANT_ERTL_MLE", + Self::Hip => "HLL_VARIANT_HIP", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "HLL_VARIANT_UNSPECIFIED" => Some(Self::Unspecified), + "HLL_VARIANT_REGULAR" => Some(Self::Regular), + "HLL_VARIANT_ERTL_MLE" => Some(Self::ErtlMle), + "HLL_VARIANT_HIP" => Some(Self::Hip), + _ => None, + } + } +} +/// KLLState is the portable state of a KLL quantile sketch. +/// +/// The items array is partitioned into compaction levels by the levels\[\] array: +/// items\[ levels[i\] .. levels\[i+1\] ) are the retained items at level i. +/// +/// Derived state that must be recomputed on load (not serialized): +/// capacity_cache — computed from k, m, and level boundaries. +/// level0_capacity — computed from k and num_levels. +/// top_height — equals num_levels - 1. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct KllState { + /// Target compactor capacity k. Must be >= 8. + #[prost(uint32, tag = "1")] + pub k: u32, + /// Minimum compactor size m. Must satisfy 2 <= m <= k. + #[prost(uint32, tag = "2")] + pub m: u32, + /// Number of levels currently in use. + #[prost(uint32, tag = "3")] + pub num_levels: u32, + /// Level boundary indices into items\[\], length = num_levels + 1. + /// levels\[0\] is always 0; levels\[num_levels\] = len(items). + #[prost(uint32, repeated, tag = "4")] + pub levels: ::prost::alloc::vec::Vec, + /// All retained samples in level order, length = levels\[num_levels\]. + #[prost(double, repeated, tag = "5")] + pub items: ::prost::alloc::vec::Vec, + /// Random bit generator state for deterministic compaction continuation. + /// Required for sketches that will receive further updates after loading. + /// Consumers that only query may ignore this field. + #[prost(message, optional, tag = "6")] + pub coin: ::core::option::Option, +} +/// CoinState is the RNG used by KLL's probabilistic compaction. +/// Both Go and Rust use an identical xorshift-based generator. +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct CoinState { + /// Xorshift generator internal state word. + #[prost(uint64, tag = "1")] + pub state: u64, + /// Up to 64 random bits buffered for single-bit coin flips. + #[prost(uint64, tag = "2")] + pub bit_cache: u64, + /// Number of valid bits remaining in bit_cache (0–64). + #[prost(uint32, tag = "3")] + pub remaining_bits: u32, +} +/// DDSketchState is the portable state of a DDSketch quantile sketch. +/// +/// Only alpha is required to reconstruct the index mapping. Consumers must +/// recompute all derived mapping values on load: +/// gamma = (1.0 + alpha) / (1.0 - alpha) +/// log_gamma = ln(gamma) +/// inv_log_gamma = 1.0 / log_gamma +/// +/// Bucket indices: a value v maps to bucket floor(ln(v) * inv_log_gamma). +/// Stored bucket absolute_index = array_index + store_offset. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DdSketchState { + /// Relative accuracy guarantee. Required. Must satisfy 0 < alpha < 1. + #[prost(double, tag = "1")] + pub alpha: f64, + /// Bucket count array in index order (ascending absolute bucket index). + /// Absolute index of store_counts\[i\] is i + store_offset. + #[prost(uint64, repeated, tag = "2")] + pub store_counts: ::prost::alloc::vec::Vec, + /// Absolute bucket index corresponding to store_counts\[0\]. + /// May be negative (values < 1.0 map to negative bucket indices). + #[prost(sint32, tag = "3")] + pub store_offset: i32, + /// Total number of values added. + #[prost(uint64, tag = "4")] + pub count: u64, + /// Sum of all values added (for mean computation). + #[prost(double, tag = "5")] + pub sum: f64, + /// Minimum value observed. +Inf when the sketch is empty. + #[prost(double, tag = "6")] + pub min: f64, + /// Maximum value observed. -Inf when the sketch is empty. + #[prost(double, tag = "7")] + pub max: f64, +} +/// UnivMonState is the portable state of a Universal Monitoring (UnivMon) sketch. +/// +/// UnivMon is a hierarchy of L Count Sketches paired with L heavy-hitter heaps. +/// An item's hash trailing-zero count determines which layers receive it, giving +/// each layer a geometrically decreasing sample of the stream. +/// +/// All layers share the same sketch dimensions and heap capacity. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UnivMonState { + /// Number of layers L in the hierarchy (inclusive of all levels). + #[prost(uint32, tag = "1")] + pub layer_size: u32, + /// Count Sketch dimensions shared by all layers. + #[prost(uint32, tag = "2")] + pub sketch_rows: u32, + #[prost(uint32, tag = "3")] + pub sketch_cols: u32, + /// Heavy-hitter heap capacity shared by all layers. + #[prost(uint32, tag = "4")] + pub heap_size: u32, + /// Total items inserted across all layers (the "bucket size" counter). + #[prost(uint64, tag = "5")] + pub bucket_size: u64, + /// Per-layer state, in order from layer 0 (finest) to layer_size-1 (coarsest). + /// Length must equal layer_size. + #[prost(message, repeated, tag = "6")] + pub layers: ::prost::alloc::vec::Vec, +} +/// UnivMonLayer is the joint state of one UnivMon layer. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UnivMonLayer { + /// The Count Sketch accumulating items at this layer. + #[prost(message, optional, tag = "1")] + pub sketch: ::core::option::Option, + /// The heavy-hitter heap for this layer. + #[prost(message, optional, tag = "2")] + pub heap: ::core::option::Option, +} +/// HydraState is the portable state of a Hydra multi-sketch framework. +/// +/// Hydra maintains a grid of row_num child sketches (cells), each of the +/// same type (counter_type). Items are routed to a specific row cell using a +/// position hash derived from the item's subkey. An optional global "big +/// counter" sketch aggregates the full stream. +/// +/// Current implementations set col_num = 1 (one sketch per row). The field is +/// included for schema completeness and future extensions. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct HydraState { + /// Number of sketch rows (D / number of subpopulations). + #[prost(uint32, tag = "1")] + pub row_num: u32, + /// Number of sketch columns per row. Currently always 1. + #[prost(uint32, tag = "2")] + pub col_num: u32, + /// The sketch type used for every cell. + #[prost(enumeration = "HydraCounterType", tag = "3")] + pub counter_type: i32, + /// Serialized cells in row-major order, length = row_num * col_num. + /// Each cell's oneof field must match counter_type. + #[prost(message, repeated, tag = "4")] + pub cells: ::prost::alloc::vec::Vec, + /// Optional global sketch covering the entire stream. + /// Absent when global counter is disabled (enable_global_counter = false). + #[prost(message, optional, tag = "5")] + pub big_counter: ::core::option::Option, + /// Seed index used for subpopulation routing (Go: seedHydra, Rust: HYDRA_SEED). + /// Both libraries default to 6. + #[prost(uint32, tag = "6")] + pub seed_index: u32, + /// True when per-cell TopK tracking is enabled. + #[prost(bool, tag = "7")] + pub enable_topk: bool, + /// True when fanout subkey expansion is active. + #[prost(bool, tag = "8")] + pub fanout_subkeys: bool, +} +/// HydraCell holds the serialized state of one Hydra grid cell. +/// Exactly one field in the oneof must be set, and it must match the parent +/// HydraState.counter_type. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct HydraCell { + #[prost(oneof = "hydra_cell::Sketch", tags = "1, 2, 3, 4, 5")] + pub sketch: ::core::option::Option, +} +/// Nested message and enum types in `HydraCell`. +pub mod hydra_cell { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Sketch { + #[prost(message, tag = "1")] + CountMin(super::CountMinState), + #[prost(message, tag = "2")] + CountSketch(super::CountSketchState), + #[prost(message, tag = "3")] + Hll(super::HyperLogLogState), + #[prost(message, tag = "4")] + Kll(super::KllState), + #[prost(message, tag = "5")] + Univmon(super::UnivMonState), + } +} +/// HydraCounterType identifies the sketch algorithm used inside Hydra cells. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum HydraCounterType { + Unspecified = 0, + CountMin = 1, + CountSketch = 2, + Hll = 3, + Kll = 4, + Univmon = 5, +} +impl HydraCounterType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "HYDRA_COUNTER_TYPE_UNSPECIFIED", + Self::CountMin => "HYDRA_COUNTER_TYPE_COUNT_MIN", + Self::CountSketch => "HYDRA_COUNTER_TYPE_COUNT_SKETCH", + Self::Hll => "HYDRA_COUNTER_TYPE_HLL", + Self::Kll => "HYDRA_COUNTER_TYPE_KLL", + Self::Univmon => "HYDRA_COUNTER_TYPE_UNIVMON", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "HYDRA_COUNTER_TYPE_UNSPECIFIED" => Some(Self::Unspecified), + "HYDRA_COUNTER_TYPE_COUNT_MIN" => Some(Self::CountMin), + "HYDRA_COUNTER_TYPE_COUNT_SKETCH" => Some(Self::CountSketch), + "HYDRA_COUNTER_TYPE_HLL" => Some(Self::Hll), + "HYDRA_COUNTER_TYPE_KLL" => Some(Self::Kll), + "HYDRA_COUNTER_TYPE_UNIVMON" => Some(Self::Univmon), + _ => None, + } + } +} +/// CocoSketchState is the portable state of a CocoSketch flow-size estimator. +/// +/// The bucket table is stored flat in row-major order (d rows × width cols). +/// Element [r][c] is at index r * width + c. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CocoSketchState { + /// Number of hash rows. + #[prost(uint32, tag = "1")] + pub d: u32, + /// Number of buckets per row. + #[prost(uint32, tag = "2")] + pub width: u32, + /// Full hash stored in each bucket, length = d * width. + /// Zero means the bucket is empty (has_keys\[i\] == false). + #[prost(uint64, repeated, tag = "3")] + pub hashes: ::prost::alloc::vec::Vec, + /// Cumulative count value per bucket, length = d * width. + #[prost(uint64, repeated, tag = "4")] + pub vals: ::prost::alloc::vec::Vec, + /// Whether each bucket holds a valid key entry, length = d * width. + #[prost(bool, repeated, tag = "5")] + pub has_keys: ::prost::alloc::vec::Vec, +} +/// ElasticState is the portable state of an Elastic Sketch. +/// +/// The Elastic Sketch has a heavy part (one bucket per index) and a light +/// Count-Min layer. The heavy part is serialized as parallel arrays. +/// The light layer is stored as a CountMinState with FLOAT64 counters. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ElasticState { + /// Number of heavy buckets. + #[prost(uint32, tag = "1")] + pub bucket_count: u32, + /// Per-bucket flow identifiers (strings), length = bucket_count. + /// Empty string means the bucket is unoccupied. + #[prost(string, repeated, tag = "2")] + pub flow_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// Positive vote counts per bucket, length = bucket_count. + #[prost(sint32, repeated, tag = "3")] + pub vote_pos: ::prost::alloc::vec::Vec, + /// Negative vote counts per bucket, length = bucket_count. + #[prost(sint32, repeated, tag = "4")] + pub vote_neg: ::prost::alloc::vec::Vec, + /// Whether each bucket is in eviction state, length = bucket_count. + #[prost(bool, repeated, tag = "5")] + pub evictions: ::prost::alloc::vec::Vec, + /// Light Count-Min layer (FLOAT64 counters). + #[prost(message, optional, tag = "6")] + pub light: ::core::option::Option, +} +/// SketchEnvelope is the portable container for all sketch transfers. +/// Producers fill exactly one field inside sketch_state. +/// Consumers check format_version first, then dispatch on the oneof. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SketchEnvelope { + /// Schema version. Consumers should reject envelopes whose version exceeds + /// the highest version they understand. + /// 1 = CountMin, Count, HLL, KLL, DDSketch + /// 2 = UnivMon, Hydra (reserved) + /// 3 = CocoSketch, ElasticSketch (reserved) + #[prost(uint32, tag = "1")] + pub format_version: u32, + /// Library and build info of the producing side. + #[prost(message, optional, tag = "2")] + pub producer: ::core::option::Option, + /// Complete hashing configuration. Consumers must validate this against their + /// own configuration before performing updates or queries on the loaded sketch. + /// Mismatches do not prevent loading but will cause diverging results. + #[prost(message, optional, tag = "3")] + pub hash_spec: ::core::option::Option, + /// The sketch payload. Exactly one field must be set. + #[prost( + oneof = "sketch_envelope::SketchState", + tags = "10, 11, 12, 13, 14, 15, 16, 17, 18" + )] + pub sketch_state: ::core::option::Option, +} +/// Nested message and enum types in `SketchEnvelope`. +pub mod sketch_envelope { + /// The sketch payload. Exactly one field must be set. + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum SketchState { + #[prost(message, tag = "10")] + CountMin(super::CountMinState), + #[prost(message, tag = "11")] + CountSketch(super::CountSketchState), + #[prost(message, tag = "12")] + Hll(super::HyperLogLogState), + #[prost(message, tag = "13")] + Kll(super::KllState), + #[prost(message, tag = "14")] + Ddsketch(super::DdSketchState), + #[prost(message, tag = "15")] + Univmon(super::UnivMonState), + #[prost(message, tag = "16")] + Hydra(super::HydraState), + #[prost(message, tag = "17")] + Coco(super::CocoSketchState), + #[prost(message, tag = "18")] + Elastic(super::ElasticState), + } +} diff --git a/tools/gen-proto/Cargo.toml b/tools/gen-proto/Cargo.toml new file mode 100644 index 0000000..0cc4ec4 --- /dev/null +++ b/tools/gen-proto/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "gen-proto" +version = "0.0.0" +edition = "2024" +publish = false +description = "Internal maintainer tool that regenerates src/proto/generated/ from proto/*.proto." + +[dependencies] +prost-build = "0.13" +protoc-bin-vendored = "3" + +# Standalone workspace so this crate is fully isolated from the parent +# `asap_sketchlib` package. It must not appear in the published crate's +# build graph or Cargo.lock. +[workspace] diff --git a/tools/gen-proto/src/main.rs b/tools/gen-proto/src/main.rs new file mode 100644 index 0000000..1de6ad1 --- /dev/null +++ b/tools/gen-proto/src/main.rs @@ -0,0 +1,94 @@ +//! Maintainer-only tool that regenerates the vendored prost output under +//! `src/proto/generated/` from the `.proto` files in `proto/`. +//! +//! Run from the repository root with: +//! +//! ```bash +//! cargo run --manifest-path tools/gen-proto/Cargo.toml +//! ``` +//! +//! CI enforces that the committed output matches the result of running this +//! tool (see `.github/workflows/ci.yml`). + +use std::fs; +use std::path::{Path, PathBuf}; + +// Inner attributes (`#![...]`) cannot appear inside an `include!` expansion, +// so this header is restricted to comments. Module-level attributes such as +// `#[rustfmt::skip]` and `#[allow(clippy::all)]` are applied to the wrapping +// `pub mod sketchlib { ... }` in `src/proto.rs` instead. +const HEADER: &str = "\ +// @generated by tools/gen-proto -- DO NOT EDIT. +// +// Regenerate with: +// cargo run --manifest-path tools/gen-proto/Cargo.toml +// +// Source of truth: proto/**/*.proto +"; + +const PROTO_FILES: &[&str] = &[ + "common/common.proto", + "countminsketch/countminsketch.proto", + "countsketch/countsketch.proto", + "hll/hll.proto", + "kll/kll.proto", + "ddsketch/ddsketch.proto", + "univmon/univmon.proto", + "hydra/hydra.proto", + "cocosketch/cocosketch.proto", + "elasticsketch/elasticsketch.proto", + "sketchlib.proto", +]; + +fn main() { + let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let repo_root = manifest_dir + .parent() + .and_then(Path::parent) + .expect("tools/gen-proto must live two levels below the repo root"); + + let proto_dir = repo_root.join("proto"); + let out_dir = repo_root.join("src/proto/generated"); + + fs::create_dir_all(&out_dir).expect("failed to create generated proto directory"); + + let protoc = + protoc_bin_vendored::protoc_bin_path().expect("failed to locate vendored protoc binary"); + // SAFETY: single-threaded maintainer tool; setting PROTOC before invoking + // prost-build is the documented way to override the protoc binary. + unsafe { + std::env::set_var("PROTOC", protoc); + } + + let protos: Vec = PROTO_FILES.iter().map(|p| proto_dir.join(p)).collect(); + + prost_build::Config::new() + .out_dir(&out_dir) + .compile_protos(&protos, &[proto_dir.clone()]) + .expect("prost_build failed to compile proto files"); + + prepend_header_to_generated(&out_dir); + + eprintln!("Generated proto code under {}", out_dir.display()); +} + +fn prepend_header_to_generated(out_dir: &Path) { + for entry in fs::read_dir(out_dir).expect("failed to read generated directory") { + let entry = entry.expect("failed to iterate generated directory"); + let path = entry.path(); + if path.extension().and_then(|e| e.to_str()) != Some("rs") { + continue; + } + let body = fs::read_to_string(&path) + .unwrap_or_else(|err| panic!("failed to read {}: {err}", path.display())); + if body.starts_with(HEADER) { + continue; + } + let mut with_header = String::with_capacity(HEADER.len() + body.len() + 1); + with_header.push_str(HEADER); + with_header.push('\n'); + with_header.push_str(&body); + fs::write(&path, with_header) + .unwrap_or_else(|err| panic!("failed to write {}: {err}", path.display())); + } +} From a13f353ca5dae7322b475a2022834437e824620a Mon Sep 17 00:00:00 2001 From: GordonYuanyc Date: Thu, 14 May 2026 07:34:26 +0000 Subject: [PATCH 2/2] ci(proto): commit tools/gen-proto Cargo.lock so --locked works The proto-vendored-up-to-date job invokes the regenerator with `--locked` so that CI uses the exact same `prost-build` version the maintainer used when committing `src/proto/generated/`. Without a checked-in lockfile this fails immediately with: error: cannot create the lock file ... because --locked was passed Track `tools/gen-proto/Cargo.lock` via an explicit allow-list override in `.gitignore` (the global `Cargo.lock` rule keeps applying to the main crate's lockfile, but is intentionally negated for the maintainer-only tool). Co-authored-by: Cursor --- .gitignore | 6 +- tools/gen-proto/Cargo.lock | 646 +++++++++++++++++++++++++++++++++++++ 2 files changed, 651 insertions(+), 1 deletion(-) create mode 100644 tools/gen-proto/Cargo.lock diff --git a/.gitignore b/.gitignore index dc7800c..a6fbfa9 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,8 @@ profile.json.gz # Local binaries binary -Cargo.lock \ No newline at end of file +Cargo.lock +# Track the lockfile for the maintainer-only `tools/gen-proto` so that CI's +# vendored-proto drift check uses the same `prost-build` version the +# maintainer used when committing `src/proto/generated/`. +!/tools/gen-proto/Cargo.lock \ No newline at end of file diff --git a/tools/gen-proto/Cargo.lock b/tools/gen-proto/Cargo.lock new file mode 100644 index 0000000..13170e8 --- /dev/null +++ b/tools/gen-proto/Cargo.lock @@ -0,0 +1,646 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "bitflags" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "gen-proto" +version = "0.0.0" +dependencies = [ + "prost-build", + "protoc-bin-vendored", +] + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", + "wasip3", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "multimap" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "petgraph" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" +dependencies = [ + "heck", + "itertools", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" +dependencies = [ + "prost", +] + +[[package]] +name = "protoc-bin-vendored" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c381df33c98266b5f08186583660090a4ffa0889e76c7e9a5e175f645a67fa" +dependencies = [ + "protoc-bin-vendored-linux-aarch_64", + "protoc-bin-vendored-linux-ppcle_64", + "protoc-bin-vendored-linux-s390_64", + "protoc-bin-vendored-linux-x86_32", + "protoc-bin-vendored-linux-x86_64", + "protoc-bin-vendored-macos-aarch_64", + "protoc-bin-vendored-macos-x86_64", + "protoc-bin-vendored-win32", +] + +[[package]] +name = "protoc-bin-vendored-linux-aarch_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c350df4d49b5b9e3ca79f7e646fde2377b199e13cfa87320308397e1f37e1a4c" + +[[package]] +name = "protoc-bin-vendored-linux-ppcle_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55a63e6c7244f19b5c6393f025017eb5d793fd5467823a099740a7a4222440c" + +[[package]] +name = "protoc-bin-vendored-linux-s390_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dba5565db4288e935d5330a07c264a4ee8e4a5b4a4e6f4e83fad824cc32f3b0" + +[[package]] +name = "protoc-bin-vendored-linux-x86_32" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8854774b24ee28b7868cd71dccaae8e02a2365e67a4a87a6cd11ee6cdbdf9cf5" + +[[package]] +name = "protoc-bin-vendored-linux-x86_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b38b07546580df720fa464ce124c4b03630a6fb83e05c336fea2a241df7e5d78" + +[[package]] +name = "protoc-bin-vendored-macos-aarch_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89278a9926ce312e51f1d999fee8825d324d603213344a9a706daa009f1d8092" + +[[package]] +name = "protoc-bin-vendored-macos-x86_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81745feda7ccfb9471d7a4de888f0652e806d5795b61480605d4943176299756" + +[[package]] +name = "protoc-bin-vendored-win32" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95067976aca6421a523e491fce939a3e65249bac4b977adee0ee9771568e8aa3" + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "wasip2" +version = "1.0.3+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +dependencies = [ + "wit-bindgen 0.57.1", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", +] + +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"