diff --git a/.gitattributes b/.gitattributes index a74c4ff..5a8705b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,68 @@ +# .gitattributes — Rust (GitHub-hosted) +# +# Sources: GitHub Docs (line endings), git-scm gitattributes (diff=rust), +# gitattributes/gitattributes Rust.gitattributes + Common.gitattributes, +# github-linguist overrides. -*.rs linguist-language=Rust +# Default: detect text, normalize to LF in the repository +* text=auto -*.html linguist-detectable=false -*.sh linguist-detectable=false -*.vimrc linguist-detectable=false +# --- Source --- +*.rs text eol=lf diff=rust +*.toml text +Cargo.lock text +Cargo.toml text +rust-toolchain text +rust-toolchain.toml text + +# --- Scripts --- +*.bash text eol=lf +*.bat text eol=crlf +*.cmd text eol=crlf +*.ps1 text eol=crlf +*.sh text eol=lf +*.zsh text eol=lf + +# --- Docs / meta --- +*.adoc text +*.markdown text diff=markdown +*.md text diff=markdown +*.txt text +AUTHORS text +CHANGELOG text +CHANGES text +CONTRIBUTING text +COPYING text +LICENSE text +NEWS text +README text +TODO text +.gitattributes text +.gitignore text + +# --- Serialisation --- +*.json text +*.xml text +*.yaml text +*.yml text + +# --- Binary --- +*.a binary +*.dll binary +*.dylib binary +*.exe binary +*.rlib binary +*.so binary + +# --- Archives / images (common) --- +*.gif binary +*.gz binary +*.ico binary +*.jpeg binary +*.jpg binary +*.png binary +*.tar binary +*.zip binary + +# --- GitHub Linguist --- +**/target/** linguist-generated diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d6272ac..6b3fc9c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,9 +33,6 @@ jobs: with: components: clippy - - name: Install pinned nightly rustfmt - run: rustup toolchain install nightly-2026-08-08 --profile minimal --component rustfmt - - uses: Swatinem/rust-cache@v2 - name: cargo test (all targets) @@ -53,8 +50,14 @@ jobs: - name: cargo doc run: RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --locked + - name: Install pinned nightly rustfmt + run: rustup toolchain install nightly-2026-09-10 --profile minimal --component rustfmt + - name: rustfmt - run: RUSTUP_TOOLCHAIN=nightly-2026-08-08 ./scripts/fmt --check + env: + RUSTFMT_TOOLCHAIN: nightly-2026-09-10 + RUSTUP_TOOLCHAIN: nightly-2026-09-10 + run: ./scripts/fmt --check - name: DOC_76 checker run: python3 scripts/check_doc_76.py @@ -65,6 +68,9 @@ jobs: - name: DERIVE_LAYOUT checker run: python3 scripts/check_derives.py + - name: cargo build (examples) + run: cargo build --examples --locked + - name: cargo build (example) run: cargo build --example build_histogram --locked @@ -82,4 +88,4 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: cargo check (library) - run: cargo +1.74.0 check --lib --locked + run: cargo check --lib --locked diff --git a/.gitignore b/.gitignore index 8e8b085..6b5e062 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,27 @@ # directories (by name) -/_build/ -/_build-ci/ -/scripts/__pycache__/ +/_analyses/ + +/.idea/ + /scratch/ /target/ # directories (by pattern) +**/__pycache__/ + +**/.mypy_cache/ +**/.pytest_cache/ +**/.ruff_cache/ + # files (by name) .DS_Store +.ruby-version # files (by pattern) @@ -21,7 +29,45 @@ **/*.rs.bk # These are backup files generated by rustfmt *~ +*.*~ +*.???_obj +*.a +*.app +*.bak +*.class +*.diff +*.dll +*.dylib +*.exe +*.gch +*.gem +*.idb +*.ilk +*.lib +*.log +*.ncb +*.o +*.obj +*.opensdf +*.opt +*.org +*.out +*.pch +*.pdb +*.pyc +*.pyo +*.res +*.sbr +*.scc +*.sdf +*.so +*.suo +*.sw[ponm] *.swp +*.test +*.tlog *.tmp +*.xcuserstate *.zip + diff --git a/.vimrc b/.vimrc index d34bf9e..9546145 100644 --- a/.vimrc +++ b/.vimrc @@ -1,4 +1,4 @@ -" Synesis C/C++ project .vimrc — aligned with .sis/.vscode/c_cxx/settings.json +" Synesis Rust project .vimrc — aligned with .vscode/settings.json (Rust) set nocompatible filetype indent plugin on @@ -17,12 +17,12 @@ set fixeol set list set listchars=tab:->,trail:-,extends:>,precedes:<,nbsp:+ -" editor.detectIndentation: false — global defaults (editor.tabSize: 2, insertSpaces: false) -set tabstop=2 -set shiftwidth=2 -set softtabstop=2 -set noexpandtab +" editor.detectIndentation: false — global defaults (editor.tabSize: 4, insertSpaces: true) set colorcolumn=76 +set expandtab +set shiftwidth=4 +set softtabstop=4 +set tabstop=4 " colorcolumn draws a full-column tint in Vim (not a VS Code-style 1px line). " Keep it subtle via the ColorColumn highlight group; reapply after colorscheme changes. @@ -40,30 +40,30 @@ autocmd ColorScheme * call s:ConfigureColorColumn() " files.trimTrailingWhitespace autocmd BufWritePre * %s/\s\+$//e -augroup sis_c_cxx +augroup sis_rust autocmd! + " [bat] + autocmd FileType bat,dosbatch setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 colorcolumn=60,76 + " [c] / [cpp] autocmd FileType c,cpp setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 colorcolumn=60,64,68,72,76 - " [rust] - autocmd FileType rs setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 colorcolumn=76 - " [cmake] autocmd FileType cmake setlocal noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 - " [shellscript] - autocmd FileType sh,bash,zsh setlocal expandtab tabstop=2 shiftwidth=2 softtabstop=2 colorcolumn=60,76 - - " [bat] - autocmd FileType bat,dosbatch setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 colorcolumn=60,76 - " [json] / [markdown] / [yaml] / [ruby] autocmd FileType json,markdown,yaml,ruby setlocal expandtab tabstop=2 shiftwidth=2 softtabstop=2 " [python] autocmd FileType python setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 colorcolumn=60,76 + " [rust] + autocmd FileType rust setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 colorcolumn=76 + + " [shellscript] + autocmd FileType sh,bash,zsh setlocal expandtab tabstop=2 shiftwidth=2 softtabstop=2 colorcolumn=60,76 + " [toml] autocmd FileType toml setlocal noexpandtab tabstop=2 shiftwidth=2 softtabstop=2 augroup END diff --git a/.vscode/settings.json b/.vscode/settings.json index f1f32fd..6f3e9c2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "[json]": { - "editor.insertSpaces": false, + "editor.insertSpaces": true, "editor.tabSize": 2, }, "[markdown]": { @@ -18,15 +18,23 @@ "editor.tabSize": 2, }, "[rust]": { + "editor.defaultFormatter": "rust-lang.rust-analyzer", + "editor.formatOnSave": true, "editor.insertSpaces": true, "editor.rulers": [ 60, 76 ], "editor.tabSize": 4, }, + "[shellscript]": { + "editor.insertSpaces": true, + "editor.rulers": [ 60, 76 ], + "editor.tabSize": 2, + }, "[toml]": { "editor.insertSpaces": false, "editor.tabSize": 2, }, "cmake.configureOnOpen": false, + "debug.allowBreakpointsEverywhere": true, "editor.detectIndentation": false, "editor.insertSpaces": false, "editor.renderWhitespace": "all", @@ -35,10 +43,22 @@ "files.insertFinalNewline": true, "files.trimTrailingWhitespace": true, "git.mergeEditor": false, + "rust-analyzer.cargo.buildScripts.enable": true, + "rust-analyzer.cargo.features": [], "rust-analyzer.cargo.noDefaultFeatures": true, - "rust-analyzer.cargo.features": [ - "default", - ], + "rust-analyzer.check.allTargets": true, + "rust-analyzer.check.command": "clippy", + "rust-analyzer.checkOnSave": true, "rust-analyzer.completion.autoimport.enable": false, + "rust-analyzer.debug.engine": "vadimcn.vscode-lldb", + "rust-analyzer.debug.openDebugPane": true, + "rust-analyzer.procMacro.enable": true, + "rust-analyzer.rustfmt.overrideCommand": [ + "rustup", + "run", + "nightly-2026-09-10", + "rustfmt", + "--unstable-features", + ], "rust-analyzer.showUnlinkedFileNotification": false, } diff --git a/CHANGES.md b/CHANGES.md index 9fe559c..862f3a4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,15 @@ # p99.Rust - Changes +## 0.0.5 - 12th September 2026 + +* added crate-level documentation describing the histogram API, percentile calculations, installation, and examples; +* added the **versions** example and expanded example-build and package validation; +* refreshed pinned-nightly formatting, repository checkers, editor configuration, and package metadata; +* documented the MSRV and enabled complete docs.rs feature coverage; +* updated **base-traits**, **criterion**, and **test_help-rs** to current compatible releases; + + ## 0.0.4 - 31st August 2026 * added canonical CI workflow **.github/workflows/ci.yml** with locked stable, feature, MSRV, Clippy, rustdoc, formatting, repository checker, example, and publish validation; diff --git a/Cargo.lock b/Cargo.lock index fc81f91..9843006 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,18 +40,18 @@ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "base-traits" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69068402cce0b92d771a83fb17d617a975ce1b8122968fdd025e1ed6c7bd0d5e" +checksum = "febda1e6bd75ec4a0680596f5d8689bbc391c3213607d286ab711f3b8b091ee1" dependencies = [ "bt-rs", ] [[package]] name = "bt-rs" -version = "0.0.3" +version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c801a3e540d22c99661706133db245edae489c872cfdb2f5925b2077170285" +checksum = "5b33a0644862185265eb4bee9b1679c1ae36f8258c000f3f482210acd95f7d70" [[package]] name = "cast" @@ -61,9 +61,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.4.4" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" +checksum = "005ec2760ca554fae18df7a11195552ec576cd665632a881bc011d5bb2fd4d80" dependencies = [ "find-msvc-tools", "shlex", @@ -174,9 +174,9 @@ checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "find-msvc-tools" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" +checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" [[package]] name = "half" @@ -233,7 +233,7 @@ checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "p99" -version = "0.0.4" +version = "0.0.5" dependencies = [ "criterion", "test_help-rs", @@ -332,7 +332,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.5", ] [[package]] @@ -367,9 +367,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.4" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f" +checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9" dependencies = [ "proc-macro2", "quote", @@ -378,9 +378,9 @@ dependencies = [ [[package]] name = "test_help-rs" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2279bf04d9491e2b3bcd59cbc12eb9d7ac914c81290c8e54cdc92225dbb52cbb" +checksum = "1fbd2a2dbea40fe948ff30aab06e73ecf79ff443ec01d38dc16ed9a28e1a4847" dependencies = [ "base-traits", "bt-rs", @@ -460,18 +460,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.56" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" +checksum = "d35102a9f36d089ccae9e4c6802bc118be4487b80aaffc0ab4e0cf5ce92d2873" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.56" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" +checksum = "146c01f5ab44258da43cf276c74a2763db2ff3969c9c652c3f2de07041d0b2bc" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 34c6373..f597ce3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,4 @@ + # ########################################################## # Package @@ -11,9 +12,18 @@ categories = [ "algorithms", "development-tools::profiling", ] -description = "Low-cost generation of performance percentiles (p50, p90, p99, etc.)" +description = "Low-cost generation of performance percentiles (p50, p90, p99, etc.) (for Rust)" documentation = "https://docs.rs/p99" edition = "2021" +exclude = [ + ".cargo", + ".cursor", + ".github", + ".vimrc", + ".vscode", + "scripts", + "target", +] homepage = "https://github.com/synesissoftware/p99.Rust" keywords = [ "latency", @@ -26,7 +36,9 @@ name = "p99" readme = "README.md" repository = "https://github.com/synesissoftware/p99.Rust" rust-version = "1.74" -version = "0.0.4" +version = "0.0.5" + +# docs.rs builds with all features enabled (including binary-scaling). [package.metadata.docs.rs] all-features = true @@ -47,6 +59,10 @@ harness = false name = "build_histogram" path = "examples/build_histogram.rs" +[[example]] +name = "versions" +path = "examples/versions/main.rs" + # ########################################################## # Features @@ -58,10 +74,13 @@ default = [ # General features: # +# - "_NEVER_TO_BE_ENABLED" - this is a placeholder feature and must NEVER be specified; # - "null-feature" - a feature that has no effect (and, thus, is useful for simplifying driver scripts); +_NEVER_TO_BE_ENABLED = [] null-feature = [] + # Crate-specific features: # # - "binary-scaling" - uses binary scaling to calculate target rank, achieving higher performance with a small loss of accuracy; @@ -74,8 +93,9 @@ binary-scaling = [ # ########################################################## # Dependencies -[dependencies] +[build-dependencies] +[dependencies] [dev-dependencies] @@ -83,9 +103,9 @@ binary-scaling = [ # criterion = { version = "0.8", default-features = false, features = [ -] } -test_help-rs = { version = "0.2.1", default-features = false, features = [ -] } +]} +test_help-rs = { version = "0.2", default-features = false, features = [ +]} # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/NEWS.md b/NEWS.md index e7795b4..7a6a372 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,12 +1,13 @@ # p99.Rust - News -| Date | News Item | -| --------------------- | ----------------------------------------- | -| 31st August 2026 | [p99.Rust 0.0.4 released](https://github.com/synesissoftware/p99.Rust/releases/tag/0.0.4) | -| 14th July 2026 | [p99.Rust 0.0.3 released](https://github.com/synesissoftware/p99.Rust/releases/tag/0.0.3) | -| 13th July 2026 | [p99.Rust 0.0.2 released](https://github.com/synesissoftware/p99.Rust/releases/tag/0.0.2) | -| 26th June 2026 | [p99.Rust 0.0.1 released](https://github.com/synesissoftware/p99.Rust/releases/tag/0.0.1) | +| Date | News Item | Details | +| ---------------- | --------- | --------------------------------- | +| 12th September 2026 | [p99.Rust 0.0.5 released](https://github.com/synesissoftware/p99.Rust/releases/tag/0.0.5) | Documentation, examples, and tooling updates | +| 31st August 2026 | [p99.Rust 0.0.4 released](https://github.com/synesissoftware/p99.Rust/releases/tag/0.0.4) | Canonical CI and Cargo metadata | +| 14th July 2026 | [p99.Rust 0.0.3 released](https://github.com/synesissoftware/p99.Rust/releases/tag/0.0.3) | Standardised project boilerplate | +| 13th July 2026 | [p99.Rust 0.0.2 released](https://github.com/synesissoftware/p99.Rust/releases/tag/0.0.2) | binary-scaling percentile feature | +| 26th June 2026 | [p99.Rust 0.0.1 released](https://github.com/synesissoftware/p99.Rust/releases/tag/0.0.1) | First public release | - + diff --git a/README.md b/README.md index 5eedee0..72bc827 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ Low-cost generation of performance percentiles (p50, p90, p99, p99.9, etc.). - [Project Information](#project-information) - [Where to get help](#where-to-get-help) - [Contribution guidelines](#contribution-guidelines) + - [Minimum Supported Rust Version (MSRV)](#minimum-supported-rust-version-msrv) - [Dependencies](#dependencies) - [Development Dependencies](#development-dependencies) - [License](#license) @@ -264,6 +265,15 @@ cargo run --example build_histogram --features binary-scaling Defect reports, feature requests, and pull requests are welcome on https://github.com/synesissoftware/p99.Rust. +### Minimum Supported Rust Version (MSRV) + +The declared Minimum Supported Rust Version (MSRV) for **p99.Rust** is **1.74**. + +This MSRV guarantee applies to the library crate itself, its runtime dependencies (`[dependencies]`), and its build dependencies (`[build-dependencies]`). Downstream consumers compiling this crate as a dependency are guaranteed that it builds cleanly on the declared MSRV toolchain. + +Development dependencies (`[dev-dependencies]`, such as benchmarking frameworks like **criterion**) may require newer Rust toolchains for local development or performance testing. These dev-dependencies are never fetched or compiled by downstream consumers and do not affect the library's MSRV guarantee. + + ### Dependencies **p99.Rust** has no (non-development) dependencies. diff --git a/TODO.md b/TODO.md index 69668ad..7add0a3 100644 --- a/TODO.md +++ b/TODO.md @@ -10,13 +10,13 @@ ## Functional improvements -* [x] ~~~`Debug` form~~~; -* [x] ~~~binary scaling~~~; +* [x] ~~~`Debug` form~~~ - ✅; +* [x] ~~~binary scaling~~~ - ✅; ## Performance improvements -* [x] ~~~binary scaling~~~; +* [x] ~~~binary scaling~~~ - ✅; ## Packaging improvements diff --git a/examples/versions/main.rs b/examples/versions/main.rs new file mode 100644 index 0000000..9886976 --- /dev/null +++ b/examples/versions/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("{} v{}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"),); +} diff --git a/rustfmt.toml b/rustfmt.toml index b912750..6ff4572 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,20 +1,16 @@ - -# rustfmt.toml for p99 (p99.Rust) -# -# Requires the pinned nightly rustfmt toolchain used by scripts/fmt: +# rustfmt.toml # -# ./scripts/fmt +# Synesis Information Systems — gold rustfmt configuration for SIS Rust +# crates. # -# Or: +# Requires pinned nightly rustfmt with unstable features. Prefer: # -# RUSTFMT="$(rustup which --toolchain nightly-2026-08-08 rustfmt)" cargo fmt -- --unstable-features +# ./scripts/fmt # -# The wrapper uses nightly-2026-08-08 by default. +# Default pin (see scripts/fmt): nightly-2026-09-10 # -# Based on rustfmt.toml circa cargo-fmt 1.4.37 era. -# edition/style_edition updated for Rust 2021. -# Inline comments mark values that differ from the 2021 style edition -# default. +# Layout: full option inventory, lexicographic by option name; deprecated +# or unused options remain present but commented. # array_width=60 # deprecated # attr_fn_like_width=70 # deprecated @@ -34,13 +30,13 @@ empty_item_single_line=false enum_discrim_align_threshold=0 error_on_line_overflow=false error_on_unformatted=false -# fn_args_layout="Vertical" +# fn_args_layout="Vertical" # deprecated alias of fn_params_layout # fn_call_width=60 # deprecated fn_params_layout="Vertical" fn_single_line=false +# force_code_in_doc_comments=true force_explicit_abi=true force_multiline_blocks=true -# force_code_in_doc_comments=true format_macro_bodies=true format_macro_matchers=true format_strings=false @@ -73,15 +69,19 @@ reorder_modules=true # report_todo="Never" # required_version="????" short_array_element_width_threshold=1 -# single_line_if_else_max_width=0 # deprecated show_parse_errors=true +# single_line_if_else_max_width=0 # deprecated skip_children=false space_after_colon=true space_before_colon=true spaces_around_ranges=false struct_field_align_threshold=20 struct_lit_single_line=false -style_edition="2021" +# struct_lit_trailing_comma="Vertical" +# struct_lit_width=0 # deprecated +# struct_trailing_comma="Vertical" +# struct_variant_width=0 # deprecated +# style_edition="2021" tab_spaces=4 trailing_comma="Vertical" trailing_semicolon=true @@ -93,4 +93,3 @@ use_try_shorthand=true # version= where_single_line=false wrap_comments=false - diff --git a/scripts/check_derives.py b/scripts/check_derives.py index c34617a..5c595ec 100755 --- a/scripts/check_derives.py +++ b/scripts/check_derives.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python3 """ Verify DERIVE_LAYOUT: multi-trait `#[derive(...)]` macros must be split into separate single-trait lines, ordered alphabetically by trait name, diff --git a/scripts/check_doc_76.py b/scripts/check_doc_76.py index 5d58d5b..2a10562 100755 --- a/scripts/check_doc_76.py +++ b/scripts/check_doc_76.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python3 """ Verify DOC_76: public documentation comment lines are at most 76 characters. diff --git a/scripts/check_test_names.py b/scripts/check_test_names.py index 259397e..1909373 100755 --- a/scripts/check_test_names.py +++ b/scripts/check_test_names.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python3 """ Verify RUST_TEST_NAMING: test functions and test modules use TEST_ prefix and SHOUTING_SNAKE_CASE, except words that name a specific Rust construct diff --git a/scripts/fmt b/scripts/fmt index 0a06baf..932cc02 100755 --- a/scripts/fmt +++ b/scripts/fmt @@ -1,7 +1,11 @@ #! /usr/bin/env bash +# Synesis Information Systems — gold rustfmt driver for SIS Rust crates. +# +# Uses a dated nightly only for this process (see RUSTFMT_TOOLCHAIN). Does +# not rely on rust-toolchain.toml. set -euo pipefail -RUSTFMT_TOOLCHAIN="${RUSTFMT_TOOLCHAIN:-nightly-2026-08-08}" +RUSTFMT_TOOLCHAIN="${RUSTFMT_TOOLCHAIN:-nightly-2026-09-10}" RUSTFMT="$(rustup which --toolchain "${RUSTFMT_TOOLCHAIN}" rustfmt 2>/dev/null || true)" if [[ -z "${RUSTFMT}" ]]; then echo "error: ${RUSTFMT_TOOLCHAIN} rustfmt is required (see rustfmt.toml)" >&2 @@ -10,4 +14,4 @@ if [[ -z "${RUSTFMT}" ]]; then fi export RUSTFMT -exec cargo fmt -- --unstable-features "$@" +exec env RUSTUP_TOOLCHAIN="${RUSTFMT_TOOLCHAIN}" cargo fmt --all -- --unstable-features "$@" diff --git a/src/lib.rs b/src/lib.rs index abfae2a..28b5d9a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,58 @@ +//! Low-cost performance percentile histograms for Rust. +//! +//! **p99** provides [`Histogram`], a fixed-size histogram with 64 +//! logarithmic power-of-two buckets. It records event durations and +//! approximates percentile values without retaining every observation. +//! +//! # Installation +//! +//! Reference the crate in **Cargo.toml** in the usual way: +//! +//! ```toml +//! p99 = { version = "0.0.4" } +//! ``` +//! +//! Enable the optional `binary-scaling` feature to use fixed-point +//! arithmetic when calculating the target rank for integer percentiles: +//! +//! ```toml +//! p99 = { version = "0.0.4", features = ["binary-scaling"] } +//! ``` +//! +//! # Components +//! +//! ## [`Histogram`] +//! +//! A histogram accepts durations as [`std::time::Duration`] values or as +//! integer counts in nanoseconds, microseconds, milliseconds, or seconds. +//! It supports clearing the measurements, reading counts and minimum, +//! maximum, and total duration values, and checking for arithmetic +//! overflow. +//! +//! Percentiles are approximated by interpolating within the matching +//! logarithmic bucket. The generic [`Histogram::value_at_percentile`] +//! method accepts a percentage from `0.0` through `100.0`; convenience +//! methods provide p50, p75, p90, p95, p99, p99.5, p99.9, p99.99, +//! p99.999, and p99.9999. +//! +//! # Examples +//! +//! ```rust +//! use p99::Histogram; +//! use std::time::Duration; +//! +//! let mut histogram = Histogram::default(); +//! histogram.push_event_duration(Duration::from_micros(5)); +//! histogram.push_event_time_ns(150); +//! +//! assert_eq!(2, histogram.event_count()); +//! assert_eq!(Some(150), histogram.min_event_time()); +//! assert!(histogram.value_at_p99().is_some()); +//! ``` +//! +//! See the project [README](https://github.com/synesissoftware/p99.Rust) +//! for further information. + // src/lib.rs : `Histogram` #[rustfmt::skip]