diff --git a/.gitattributes b/.gitattributes index 7beaa80..a74c4ff 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,6 @@ *.rs linguist-language=Rust + +*.html linguist-detectable=false +*.sh linguist-detectable=false +*.vimrc linguist-detectable=false diff --git a/.gitignore b/.gitignore index 3510f13..8e8b085 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ # directories (by name) /_build/ +/_build-ci/ +/scripts/__pycache__/ /scratch/ /target/ @@ -13,8 +15,6 @@ .DS_Store -#Cargo.lock - # files (by pattern) @@ -24,3 +24,4 @@ *.swp *.tmp *.zip + diff --git a/.vimrc b/.vimrc new file mode 100644 index 0000000..d34bf9e --- /dev/null +++ b/.vimrc @@ -0,0 +1,70 @@ +" Synesis C/C++ project .vimrc — aligned with .sis/.vscode/c_cxx/settings.json + +set nocompatible +filetype indent plugin on +syntax enable +set autoindent +set backspace=indent,eol,start +set hlsearch +set incsearch +set number + +" files.insertFinalNewline +set eol +set fixeol + +" editor.renderWhitespace: all +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 +set colorcolumn=76 + +" 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. +if has('termguicolors') + " set termguicolors +endif + +function! s:ConfigureColorColumn() abort + highlight ColorColumn ctermbg=236 guibg=#2a2a2a cterm=NONE gui=NONE +endfunction + +call s:ConfigureColorColumn() +autocmd ColorScheme * call s:ConfigureColorColumn() + +" files.trimTrailingWhitespace +autocmd BufWritePre * %s/\s\+$//e + +augroup sis_c_cxx + autocmd! + + " [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 + + " [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 577e52d..f1f32fd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,38 +1,44 @@ { "[json]": { - "editor.tabSize": 2 + "editor.insertSpaces": false, + "editor.tabSize": 2, + }, + "[markdown]": { + "editor.insertSpaces": true, + "editor.tabSize": 2, }, "[python]": { "editor.insertSpaces": true, "editor.rulers": [ 60, 76 ], - "editor.tabSize": 2 + "editor.tabSize": 4, }, "[ruby]": { "editor.insertSpaces": true, "editor.rulers": [ 60, 76 ], - "editor.tabSize": 2 + "editor.tabSize": 2, }, "[rust]": { "editor.insertSpaces": true, "editor.rulers": [ 60, 76 ], - "editor.tabSize": 4 + "editor.tabSize": 4, }, "[toml]": { "editor.insertSpaces": false, - "editor.tabSize": 2 + "editor.tabSize": 2, }, "cmake.configureOnOpen": false, "editor.detectIndentation": false, "editor.insertSpaces": false, "editor.renderWhitespace": "all", + "editor.rulers": [ 76 ], "editor.tabSize": 2, "files.insertFinalNewline": true, "files.trimTrailingWhitespace": true, "git.mergeEditor": false, "rust-analyzer.cargo.noDefaultFeatures": true, "rust-analyzer.cargo.features": [ - "default" + "default", ], "rust-analyzer.completion.autoimport.enable": false, - "rust-analyzer.showUnlinkedFileNotification": false + "rust-analyzer.showUnlinkedFileNotification": false, } diff --git a/CHANGES.md b/CHANGES.md index c3acb36..e2bc688 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,12 +1,15 @@ # p99.Rust CHANGES -## 0.0.2 - 13th July 2026 +## 0.0.3 - 14th July 2026 + +* standardised project boilerplate: (**.gitattributes**, **.gitignore**, **.vimrc**, **.vscode/settings.json**); project files (**CHANGES.md**, **EXAMPLES.md**, **NEWS.md**, **README.md**, **TODO.md**); -#### Changes -* Added opt-in crate feature **`"binary-scaling"`** that replaces integer division with $2^{32}$ fixed-point binary scaling for all integer-based percentile queries (`value_at_p90()`, `value_at_p95()`, `value_at_p99()`, etc.), achieving a ~1.5x to 2x speedup with a small loss of accuracy; -* Added **`"null-feature"`** -- a no-op feature that has no effect but simplifies driver scripts that conditionally pass features; +## 0.0.2 - 13th July 2026 + +* added opt-in crate feature **`"binary-scaling"`** that replaces integer division with $2^{32}$ fixed-point binary scaling for all integer-based percentile queries (`#value_at_p90()`, `#value_at_p95()`, `#value_at_p99()`, etc.), achieving a ~1.5x to 2x speedup with a small loss of accuracy; +* added **`"null-feature"`** -- a no-op feature that has no effect but simplifies driver scripts that conditionally pass features; ## 0.0.1 - 26th June 2026 diff --git a/Cargo.lock b/Cargo.lock index 52640b8..0626e91 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,6 +44,12 @@ version = "0.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb2de59cca22f51f3301a09c549b0b4a32f56e8a007d0d44b02a1ce42975b37" +[[package]] +name = "bt-rs" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4985bd0bdfcd2a13bdeaa1798240f2168998107a7939a39384c4c7608392a26" + [[package]] name = "cast" version = "0.3.0" @@ -52,9 +58,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.65" +version = "1.2.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" +checksum = "f5d6cac793997bd970000024b2934968efe83b382de4fdcf4fcb46b6ee4ad996" dependencies = [ "find-msvc-tools", "shlex", @@ -203,9 +209,9 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "memchr" -version = "2.8.2" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "num-traits" @@ -224,7 +230,7 @@ checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "p99" -version = "0.0.2" +version = "0.0.3" dependencies = [ "criterion", "test_help-rs", @@ -358,11 +364,12 @@ dependencies = [ [[package]] name = "test_help-rs" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d2df2cc6a57f53f03c47cc937df746b8f2d0f5e63b77b7d81aa30b9ceb2842" +checksum = "860ba0c1f6ec76a108a38b90425e38a84d024597cfe4deacb4f19f5a9839541d" dependencies = [ "base-traits", + "bt-rs", ] [[package]] @@ -439,18 +446,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.52" +version = "0.8.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +checksum = "b7cbbc0a705a0fd05cc3676525980d2bf5a9bc4adac6d6475209a7887cf59d19" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.52" +version = "0.8.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 568d49e..70d9f92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ license = "BSD-3-Clause" name = "p99" readme = "README.md" repository = "https://github.com/synesissoftware/p99.Rust" -version = "0.0.2" +version = "0.0.3" # ########################################################## diff --git a/EXAMPLES.md b/EXAMPLES.md new file mode 100644 index 0000000..f9dd78d --- /dev/null +++ b/EXAMPLES.md @@ -0,0 +1,9 @@ +# p99.Rust Examples + + +|Name|Source & Description|Summary| +|---|---|---| +|**build_histogram**|[examples/build_histogram/main.rs](/examples/build_histogram/main.rs)
[examples/build_histogram.md](/examples/build_histogram.md)|Lists files in the current directory whose paths match one or more shell wildcard pattern(s), using `shwild::matches()`.| + + + diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..790b5ad --- /dev/null +++ b/NEWS.md @@ -0,0 +1,11 @@ +# p99.Rust - NEWS + +| Date | News Item | +| --------------------- | ----------------------------------------- | +| 14th July 2026 | p99.Rust 0.0.3 released | +| 13th July 2026 | p99.Rust 0.0.2 released | +| 26th June 2026 | p99.Rust 0.0.1 released | + + + + diff --git a/README.md b/README.md index dca38e9..254c738 100644 --- a/README.md +++ b/README.md @@ -14,27 +14,29 @@ Low-cost generation of performance percentiles (p50, p90, p99, p99.9, etc.). - [Introduction](#introduction) - [How It Works](#how-it-works) - [Performance \& Trade-offs](#performance--trade-offs) - - [Performance Claims](#performance-claims) - - [Trade-offs \& Sacrifices](#trade-offs--sacrifices) + - [Performance Claims](#performance-claims) + - [Trade-offs \& Sacrifices](#trade-offs--sacrifices) - [Installation](#installation) - [Components](#components) - - [Constants](#constants) - - [Enumerations](#enumerations) - - [Features](#features) - - [Functions](#functions) - - [Macros](#macros) - - [Structures](#structures) - - [`Histogram`](#histogram) - - [Definition](#definition) - - [Minimal Example](#minimal-example) - - [Traits](#traits) + - [Constants](#constants) + - [Enumerations](#enumerations) + - [Features](#features) + - [Enabling `binary-scaling`](#enabling-binary-scaling) + - [Benchmark Results](#benchmark-results) + - [Functions](#functions) + - [Macros](#macros) + - [Structures](#structures) + - [`Histogram`](#histogram) + - [Definition](#definition) + - [Minimal Example](#minimal-example) + - [Traits](#traits) - [Examples](#examples) - [Project Information](#project-information) - - [Where to get help](#where-to-get-help) - - [Contribution guidelines](#contribution-guidelines) - - [Dependencies](#dependencies) - - [Dev Dependencies](#dev-dependencies) - - [License](#license) + - [Where to get help](#where-to-get-help) + - [Contribution guidelines](#contribution-guidelines) + - [Dependencies](#dependencies) + - [Dev Dependencies](#dev-dependencies) + - [License](#license) ## Introduction @@ -104,9 +106,10 @@ No public enumerations are defined at this time. The following crate features are available: -* **`binary-scaling`** *(opt-in)*: Replaces integer division in the integer-based percentile methods (`value_at_p90()`, `value_at_p95()`, `value_at_p99()`, etc.) with $2^{32}$ fixed-point binary scaling. Each percentile multiplier (e.g., `0.90` for p90) is pre-encoded as a `u32` constant and the target rank is computed via a single multiplication and a 32-bit right-shift, avoiding the cost of integer division entirely. This yields a **~1.5x to 2x speedup** for percentile queries with a negligible loss of accuracy (the scaled multiplier differs from the true value by less than $10^{-9}$). The generic `value_at_percentile(f64)` method is unaffected by this feature. +* **`"binary-scaling"`** *(opt-in)*: Replaces integer division in the integer-based percentile methods (`#value_at_p90()`, `#value_at_p95()`, `#value_at_p99()`, etc.) with $2^{32}$ fixed-point binary scaling. Each percentile multiplier (e.g., `0.90` for p90) is pre-encoded as a `u32` constant and the target rank is computed via a single multiplication and a 32-bit right-shift, avoiding the cost of integer division entirely. This yields a **~1.5x to 2x speedup** for percentile queries with a negligible loss of accuracy (the scaled multiplier differs from the true value by less than $10^{-9}$). The generic `#value_at_percentile(f64)` method is unaffected by this feature; + +* **`"null-feature"`** *(opt-in)*: A no-op feature that has no effect on the compiled library. It exists to simplify driver scripts and CI pipelines that conditionally pass `--features` flags, allowing a feature list to always be present even when no real features are needed; -* **`null-feature`** *(opt-in)*: A no-op feature that has no effect on the compiled library. It exists to simplify driver scripts and CI pipelines that conditionally pass `--features` flags, allowing a feature list to always be present even when no real features are needed. #### Enabling `binary-scaling` diff --git a/TODO.md b/TODO.md index a5c3575..df6990d 100644 --- a/TODO.md +++ b/TODO.md @@ -1,13 +1,27 @@ -# p99.Rust +# p99.Rust - TODO ## Table of Contents -- [TODOs](#todos) +- [Functional improvements](#functional-improvements) +- [Performance improvements](#performance-improvements) +- [Packaging improvements](#packaging-improvements) -## TODOs +## Functional improvements - [x] ~~~`Debug` form~~~; - [x] ~~~binary scaling~~~; + +## Performance improvements + +- [x] ~~~binary scaling~~~; + + +## Packaging improvements + +* \ + + + diff --git a/examples/build_histogram.md b/examples/build_histogram.md new file mode 100644 index 0000000..d9de094 --- /dev/null +++ b/examples/build_histogram.md @@ -0,0 +1,161 @@ +# `build_histogram.rs` + +This example demonstrates the usage of the `Histogram` struct from the `p99` crate to measure and display event durations. + +The program simulates a series of events, each with a random delay, and records their durations using a `Histogram` instance. After all events are processed, it prints the histogram in a detailed format and also calculates and displays various percentiles (p50, p75, p90, p95, p99, p99.5, p99.9, p99.99) of the recorded durations. + +The number of tries (simulated events) can be controlled by setting the `P99_TRIES` environment variable. If not set, it defaults to 100. + +```rust +// examples/build_histogram.rs : example program showing `Histogram` + +use p99::Histogram; + +#[rustfmt::skip] +use std::{ + env as std_env, + thread as std_thread, + time as std_time, +}; + +struct SimpleRng { + state: u64, +} + +// API functions + +impl SimpleRng { + fn new(seed: u64) -> Self { + Self { state: seed } + } +} + +// Mutating methods + +impl SimpleRng { + fn next(&mut self) -> u64 { + self.state = self.state.wrapping_mul(6_364_136_223_846_793_005).wrapping_add(1); + + self.state + } +} + +// Helper functions + +fn main() { + let range = match std_env::var("P99_RANGE") { + Ok(val) => match val.parse::() { + Ok(num) => num, + Err(_) => { + eprintln!("Warning: failed to parse P99_RANGE value '{}', defaulting to 1,000,000", val); + + 1_000_000 + }, + }, + Err(_) => 1_000_000, + }; + let tries = match std_env::var("P99_TRIES") { + Ok(val) => match val.parse::() { + Ok(num) => num, + Err(_) => { + eprintln!("Warning: failed to parse P99_TRIES value '{}', defaulting to 100", val); + + 100 + }, + }, + Err(_) => 100, + }; + + println!("Running Histogram example with {} tries...", tries); + + let mut histogram = Histogram::default(); + let mut rng = SimpleRng::new(12_345); + + for _ in 0..tries { + // Generate a random delay from 1 to nanoseconds. + let delay_ns = (rng.next() % range as u64) + 1; + let start = std_time::Instant::now(); + + if delay_ns < 1_000_000 { + + let busy_wait_start = std_time::Instant::now(); + while busy_wait_start.elapsed().as_nanos() < delay_ns as u128 { + std::hint::black_box(1); + } + } else { + + std_thread::sleep(std_time::Duration::from_micros(delay_ns)); + } + + let elapsed = start.elapsed(); + histogram.push_event_duration(elapsed); + } + + println!("\nHistogram printed via `{{:#?}}` format:\n"); + println!("{:#?}", histogram); + + println!("\nPercentiles (approximated):"); + println!(" p50 (f64): {:?} ns", histogram.value_at_percentile(50.0)); + println!(" p50 (integer): {:?} ns", histogram.value_at_p50()); + println!(" p75 (integer): {:?} ns", histogram.value_at_p75()); + println!(" p90 (integer): {:?} ns", histogram.value_at_p90()); + println!(" p95 (integer): {:?} ns", histogram.value_at_p95()); + println!(" p99 (integer): {:?} ns", histogram.value_at_p99()); + println!(" p99.5 (integer): {:?} ns", histogram.value_at_p99_5()); + println!(" p99.9 (integer): {:?} ns", histogram.value_at_p99_9()); + println!(" p99.99 (integer): {:?} ns", histogram.value_at_p99_99()); +} +``` + +Example output: + +``` +$ P99_RANGE=1000000 P99_TRIES=10000 cargo run --release --example build_histogram + Finished `release` profile [optimized] target(s) in 0.09s + Running `target/release/examples/build_histogram` +Running Histogram example with 10000 tries... + +Histogram printed via `{:#?}` format: + +Histogram { + event_count: 10000, + event_time_total: Some( + 5009212642, + ), + has_overflowed: false, + min_event_time: Some( + 125, + ), + max_event_time: Some( + 2332375, + ), + buckets: { + "2^6": 1, + "2^7": 4, + "2^8": 4, + "2^9": 6, + "2^10": 14, + "2^11": 23, + "2^12": 49, + "2^13": 87, + "2^14": 166, + "2^15": 306, + "2^16": 658, + "2^17": 1284, + "2^18": 2627, + "2^19": 4770, + "2^21": 1, + }, +} + +Percentiles (approximated): + p50 (f64): Some(501436) ns + p50 (integer): Some(501435) ns + p75 (integer): Some(773901) ns + p90 (integer): Some(938771) ns + p95 (integer): Some(993728) ns + p99 (integer): Some(1037693) ns + p99.5 (integer): Some(1043189) ns + p99.9 (integer): Some(1047585) ns + p99.99 (integer): Some(1048575) ns +``` diff --git a/examples/build_histogram.rs b/examples/build_histogram.rs index f02eeec..2165146 100644 --- a/examples/build_histogram.rs +++ b/examples/build_histogram.rs @@ -34,6 +34,17 @@ impl SimpleRng { // Helper functions fn main() { + let range = match std_env::var("P99_RANGE") { + Ok(val) => match val.parse::() { + Ok(num) => num, + Err(_) => { + eprintln!("Warning: failed to parse P99_RANGE value '{}', defaulting to 1,000,000", val); + + 1_000_000 + }, + }, + Err(_) => 1_000_000, + }; let tries = match std_env::var("P99_TRIES") { Ok(val) => match val.parse::() { Ok(num) => num, @@ -52,11 +63,20 @@ fn main() { let mut rng = SimpleRng::new(12_345); for _ in 0..tries { - // Generate a random delay from 1 to 500 microseconds. - let delay_us = (rng.next() % 1_000) + 1; + // Generate a random delay from 1 to nanoseconds. + let delay_ns = (rng.next() % range as u64) + 1; let start = std_time::Instant::now(); - std_thread::sleep(std_time::Duration::from_micros(delay_us)); + if delay_ns < 1_000_000 { + + let busy_wait_start = std_time::Instant::now(); + while busy_wait_start.elapsed().as_nanos() < delay_ns as u128 { + std::hint::black_box(1); + } + } else { + + std_thread::sleep(std_time::Duration::from_micros(delay_ns)); + } let elapsed = start.elapsed(); histogram.push_event_duration(elapsed); diff --git a/rustfmt.toml b/rustfmt.toml index b1f362b..9dbe787 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,67 +1,94 @@ + # rustfmt.toml for p99 (p99.Rust) # +# Requires nightly rustfmt with unstable features enabled, e.g.: +# +# ./scripts/fmt +# +# Or: +# +# RUSTFMT="$(rustup which --toolchain nightly rustfmt)" cargo fmt -- --unstable-features +# # 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. -edition = "2021" -style_edition = "2021" +# array_width=60 # deprecated +# attr_fn_like_width=70 # deprecated +binop_separator="Front" +blank_lines_lower_bound=0 +blank_lines_upper_bound=3 +brace_style="SameLineWhere" +# chain_width=60 # deprecated +color="Auto" +combine_control_expr=false +comment_width=76 +condense_wildcard_suffixes=false +control_brace_style="AlwaysSameLine" +disable_all_formatting=false +edition="2021" +empty_item_single_line=false +enum_discrim_align_threshold=0 +error_on_line_overflow=false +error_on_unformatted=false +# fn_args_layout="Vertical" +# fn_call_width=60 # deprecated +fn_params_layout="Vertical" +fn_single_line=false +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 +group_imports="Preserve" +hard_tabs=false +# hide_parse_errors=false +ignore=[ +] +imports_granularity="Crate" +imports_indent="Block" +imports_layout="Vertical" +indent_style="Block" +inline_attribute_width=0 +# license_template_path="" +match_arm_blocks=true +match_arm_leading_pipes="Preserve" +match_block_trailing_comma=true +max_width=120 +merge_derives=false +# merge_imports= # deprecated +newline_style="Auto" +normalize_comments=false +normalize_doc_attributes=true +overflow_delimited_expr=false +remove_nested_parens=true +reorder_impl_items=true +reorder_imports=true +reorder_modules=true +# report_fixme="Always" +# report_todo="Never" +# required_version="????" +short_array_element_width_threshold=1 +# single_line_if_else_max_width=0 # deprecated +show_parse_errors=true +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" +tab_spaces=4 +trailing_comma="Vertical" +trailing_semicolon=true +type_punctuation_density="Wide" +unstable_features=true +use_field_init_shorthand=true +use_small_heuristics="Default" +use_try_shorthand=true +# version= +where_single_line=false +wrap_comments=false -binop_separator = "Front" -blank_lines_lower_bound = 0 -blank_lines_upper_bound = 3 # default: 1 -brace_style = "SameLineWhere" -color = "Auto" -combine_control_expr = false # default: true -comment_width = 100 # default: 80 -condense_wildcard_suffixes = false -control_brace_style = "AlwaysSameLine" -disable_all_formatting = false -empty_item_single_line = false # default: true -enum_discrim_align_threshold = 0 -error_on_line_overflow = false -error_on_unformatted = false -fn_params_layout = "Vertical" # default: "Tall" -fn_single_line = false -force_explicit_abi = true -force_multiline_blocks = true # default: false -format_macro_bodies = true -format_macro_matchers = true # default: false -format_strings = false -group_imports = "Preserve" -hard_tabs = false -ignore = [] -imports_granularity = "Crate" # default: "Preserve" -imports_indent = "Block" -imports_layout = "Vertical" # default: "Mixed" -indent_style = "Block" -inline_attribute_width = 0 -match_arm_blocks = true -match_arm_leading_pipes = "Preserve" # default: "Never" -match_block_trailing_comma = true # default: false -max_width = 120 # default: 100 -merge_derives = false # default: true -newline_style = "Auto" -normalize_comments = false -normalize_doc_attributes = true # default: false -overflow_delimited_expr = false -remove_nested_parens = true -reorder_impl_items = true # default: false -reorder_imports = true -reorder_modules = true -skip_children = false -space_after_colon = true -space_before_colon = true # default: false -spaces_around_ranges = false -struct_field_align_threshold = 40 # default: 0 -struct_lit_single_line = false # default: true -tab_spaces = 4 -trailing_comma = "Vertical" -trailing_semicolon = true -type_punctuation_density = "Wide" -use_field_init_shorthand = true # default: false -use_small_heuristics = "Default" -use_try_shorthand = true # default: false -where_single_line = false -wrap_comments = false