diff --git a/.cursor/rules/rust-standards.mdc b/.cursor/rules/rust-standards.mdc deleted file mode 100644 index 29f947d..0000000 --- a/.cursor/rules/rust-standards.mdc +++ /dev/null @@ -1,48 +0,0 @@ ---- -description: Rust coding standards for Diagnosticism.Rust (aligned with Synesis Information Systems' internal project standards) -globs: **/*.rs -alwaysApply: false ---- - -# Rust Software Quality Rules - - -## DOC_76 (The 76-Rule for Documentation Comments) - -- Documentation comments (`///`, `//!`) on **public** constructs must be at - most **76 characters** per line, including leading indentation; -- Wrap text **greedily** (pack to maximum width) — do not wrap early if the - next word fits on the current line; -- Code blocks inside doc comments (triple backticks) are exempt; -- List items in doc comments should end with a semicolon; -- Inline comments (`//`) inside functions are limited to **100 characters** - per line, wrapped greedily; -- Private/non-`pub` constructs are exempt from DOC_76 for their doc - comments; - -Run `./scripts/check_doc_76.py` to verify compliance. - - -## DERIVE_LAYOUT (Derive Layout & Formatting) - -Multi-trait `#[derive(...)]` macros must be split into separate, -single-trait lines, ordered alphabetically by trait name. Tightly coupled -traits may remain on one line: `#[derive(Eq, PartialEq)]`, -`#[derive(Ord, PartialOrd)]`. - -`rustfmt.toml` sets `merge_derives = false` to preserve this layout. - -Run `./scripts/check_derives.py` to verify compliance. - - -## RUST_TEST_NAMING - -All test methods must use `SHOUTING_SNAKE_CASE` - e.g. `TEST_PARSING()` - -except where a word in the snake case represents a specific construct (such -as a struct, enum, type, function, macro, or field name), in which case that -word must preserve its exact correct case - e.g. -`TEST_AutoBuffer_WITH_INTERNAL_SIZE()`, `TEST_doom_scope_1()`, -`TEST_type_name_only_WITH_SomeCustomType()`. - -Run `./scripts/check_test_names.py` to verify compliance. - diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..5a8705b --- /dev/null +++ b/.gitattributes @@ -0,0 +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. + +# Default: detect text, normalize to LF in the repository +* text=auto + +# --- 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 a8eedd9..9339c44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,21 +33,27 @@ 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) run: cargo test --all-targets --locked + - name: cargo test (no default features) + run: cargo test --no-default-features --locked + - name: cargo clippy run: cargo clippy --all-targets --locked -- -D warnings - 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 + env: + RUSTFMT_TOOLCHAIN: nightly-2026-09-10 + RUSTUP_TOOLCHAIN: nightly-2026-09-10 run: ./scripts/fmt --check - name: DOC_76 checker @@ -59,9 +65,27 @@ jobs: - name: DERIVE_LAYOUT checker run: python3 scripts/check_derives.py + - name: cargo build (examples) + run: cargo build --examples --locked + - name: cargo publish (dry run) run: cargo publish --dry-run --locked + msrv: + name: MSRV (1.74) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: dtolnay/rust-toolchain@1.74.0 + + - uses: Swatinem/rust-cache@v2 + + - name: cargo check (library) + # Full tests need dev-deps (criterion -> clap_lex 2024 edition); + # stable runs the complete test suite; MSRV only checks the library. + run: cargo check --lib --locked + feature: name: test-doomgram feature checks runs-on: ubuntu-latest @@ -80,18 +104,3 @@ jobs: - name: cargo doc (test-doomgram) run: RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --features test-doomgram --locked - - msrv: - name: MSRV (1.74) - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: dtolnay/rust-toolchain@1.74.0 - - - uses: Swatinem/rust-cache@v2 - - - name: cargo check (library) - # Full tests need dev-deps (criterion -> clap_lex 2024 edition); - # stable runs the complete test suite; MSRV only checks the library. - run: cargo check --lib --locked diff --git a/.gitignore b/.gitignore index 8ea0d84..6b5e062 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,27 @@ # directories (by name) -/_build/ -/scripts/__pycache__/ +/_analyses/ + +/.idea/ + /scratch/ /target/ # directories (by pattern) +**/__pycache__/ + +**/.mypy_cache/ +**/.pytest_cache/ +**/.ruff_cache/ + # files (by name) .DS_Store - -#Cargo.lock +.ruby-version # files (by pattern) @@ -22,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 df7a8b7..6f3e9c2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,10 +3,14 @@ "editor.insertSpaces": true, "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, @@ -14,23 +18,47 @@ "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", + "editor.rulers": [ 76 ], "editor.tabSize": 2, "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.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 322fa5a..416e887 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,17 @@ # Diagnosticism.Rust - Changes +## 0.4.5 - 12th September 2026 + +* removed the Rust-specific Cursor rule superseded by shared workspace standards; +* strengthened CI with no-default-features, example, documentation, formatting, and MSRV validation; +* refreshed repository metadata, editor configuration, ignore rules, and Rust formatting configuration; +* added the **versions** example and excluded development-only files from published packages; +* documented the MSRV and canonicalised **Cargo.toml** dependency metadata; +* updated **base-traits**, **criterion**, and **rand** to current compatible releases; +* improved the test-name checker and extended derive checking to the test tree; + + ## 0.4.4 - 31st August 2026 * updated dependencies; diff --git a/Cargo.lock b/Cargo.lock index d7cb316..f7917b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,24 +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" - -[[package]] -name = "bumpalo" -version = "3.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" +checksum = "5b33a0644862185265eb4bee9b1679c1ae36f8258c000f3f482210acd95f7d70" [[package]] name = "cast" @@ -67,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", @@ -169,8 +163,6 @@ dependencies = [ "num-traits", "oorandom", "page_size", - "plotters", - "rayon", "regex", "serde", "serde_json", @@ -188,31 +180,6 @@ dependencies = [ "itertools", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" - [[package]] name = "crunchy" version = "0.2.4" @@ -221,7 +188,7 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "diagnosticism" -version = "0.4.4" +version = "0.4.5" dependencies = [ "base-traits", "criterion", @@ -236,45 +203,9 @@ checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "find-msvc-tools" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" - -[[package]] -name = "futures-core" -version = "0.3.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" - -[[package]] -name = "futures-task" -version = "0.3.34" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" - -[[package]] -name = "futures-util" -version = "0.3.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" -dependencies = [ - "futures-core", - "futures-task", - "pin-project-lite", - "slab", -] - -[[package]] -name = "getrandom" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "rand_core", -] +checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" [[package]] name = "half" @@ -302,17 +233,6 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" -[[package]] -name = "js-sys" -version = "0.3.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" -dependencies = [ - "cfg-if", - "futures-util", - "wasm-bindgen", -] - [[package]] name = "libc" version = "0.2.189" @@ -334,12 +254,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "once_cell" -version = "1.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" - [[package]] name = "oorandom" version = "11.1.5" @@ -356,40 +270,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "pin-project-lite" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" - -[[package]] -name = "plotters" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" - -[[package]] -name = "plotters-svg" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" -dependencies = [ - "plotters-backend", -] - [[package]] name = "proc-macro2" version = "1.0.107" @@ -408,12 +288,6 @@ 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 = "rand" version = "0.10.2" @@ -421,7 +295,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ "chacha20", - "getrandom", "rand_core", ] @@ -431,26 +304,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" -[[package]] -name = "rayon" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - [[package]] name = "regex" version = "1.13.1" @@ -480,12 +333,6 @@ version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" -[[package]] -name = "rustversion" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" - [[package]] name = "same-file" version = "1.0.6" @@ -522,7 +369,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.5", ] [[package]] @@ -544,12 +391,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" -[[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - [[package]] name = "syn" version = "2.0.119" @@ -563,9 +404,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", @@ -598,61 +439,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasm-bindgen" -version = "0.2.127" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.127" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.127" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn 2.0.119", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.127" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "web-sys" -version = "0.3.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c435338968042f4f59a557f690a253676d47ce13ceb55d70100e7facf6620a30" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "winapi" version = "0.3.9" @@ -701,18 +487,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 26c599b..c16811c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,15 @@ categories = [ description = "Miscellaneous discrete and simple diagnostics facilities (for Rust)" documentation = "https://docs.rs/diagnosticism" edition = "2021" +exclude = [ + ".cargo", + ".cursor", + ".github", + ".vimrc", + ".vscode", + "scripts", + "target", +] homepage = "https://github.com/synesissoftware/Diagnosticism.Rust" keywords = [ "debug", @@ -27,7 +36,7 @@ name = "diagnosticism" readme = "README.md" repository = "https://github.com/synesissoftware/Diagnosticism.Rust" rust-version = "1.74" -version = "0.4.4" +version = "0.4.5" # docs.rs builds the optional `rand`-backed example path. @@ -75,12 +84,19 @@ path = "examples/flf.rs" name = "password" path = "examples/password.rs" +[[example]] +name = "versions" +path = "examples/versions/main.rs" + # ########################################################## # Features [features] +default = [ +] + # General features: # # - "_NEVER_TO_BE_ENABLED" - this is a placeholder feature and must NEVER be specified; @@ -92,6 +108,7 @@ null-feature = [] # Crate-specific features: # +# - "test-doomgram" - enables the doomgram example's `rand`-backed path; test-doomgram = [ "dep:rand", @@ -101,15 +118,21 @@ test-doomgram = [ # ########################################################## # Dependencies +[build-dependencies] + [dependencies] -base-traits = { version = "0", default-features = false, features = [ +base-traits = { version = "0.1", default-features = false, features = [ +]} +rand = { version = "0.10", optional = true, default-features = false, features = [ + "std_rng", ]} -rand = { version = "0.10", optional = true } + [dev-dependencies] -criterion = { version = "0.8" } +criterion = { version = "0.8", 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 39af012..cd46b90 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,21 +1,23 @@ # Diagnosticism.Rust - News -| Date | News Item | -| ---------------- | -------------------------------------------------------------------------------------------------- | -| 31st August 2026 | [Diagnosticism.Rust 0.4.4](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.4.4) released | -| 31st August 2026 | [Diagnosticism.Rust 0.4.3](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.4.3) released | -| 10th July 2026 | [Diagnosticism.Rust 0.4.2](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.4.2) released | -| 7th July 2026 | [Diagnosticism.Rust 0.4.1](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.4.1) released | -| 30th June 2026 | [Diagnosticism.Rust 0.4.0](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.4.0) released | -| 28th June 2026 | [Diagnosticism.Rust 0.3.2](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.3.2) released | -| 28th June 2026 | [Diagnosticism.Rust 0.3.1](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.3.1) released | -| 28th June 2026 | [Diagnosticism.Rust 0.3.0](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.3.0) released | -| 27th June 2026 | [Diagnosticism.Rust 0.2.1](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.2.1) released | -| 24th July 2025 | [Diagnosticism.Rust 0.2.0](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.2.0) released | -| 29th March 2025 | [Diagnosticism.Rust 0.1.0](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.1.0) released | -| 19th December 2024 | [Diagnosticism.Rust 0.0.2](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.0.2) released | -| 13th September 2024 | [Diagnosticism.Rust 0.0.1](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.0.1) released | -| 27th August 2024 | [Diagnosticism.Rust 0.0.0](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.0.0) released | + +| Date | News Item | Details | +| ------------------- | --------- | ------------------------------------ | +| 12th September 2026 | [Diagnosticism.Rust 0.4.5](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.4.5) released | CI, packaging, and tooling updates | +| 31st August 2026 | [Diagnosticism.Rust 0.4.4](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.4.4) released | Dependency updates | +| 31st August 2026 | [Diagnosticism.Rust 0.4.3](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.4.3) released | CI, docs.rs, and formatting pins | +| 10th July 2026 | [Diagnosticism.Rust 0.4.2](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.4.2) released | Expanded unit tests and tidying | +| 7th July 2026 | [Diagnosticism.Rust 0.4.1](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.4.1) released | Len for NanosecondsStr | +| 30th June 2026 | [Diagnosticism.Rust 0.4.0](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.4.0) released | DoomGram to_mmm/to_nmmm | +| 28th June 2026 | [Diagnosticism.Rust 0.3.2](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.3.2) released | NanosecondsStr optimisation | +| 28th June 2026 | [Diagnosticism.Rust 0.3.1](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.3.1) released | Internal implementation improvements | +| 28th June 2026 | [Diagnosticism.Rust 0.3.0](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.3.0) released | nanoseconds_to_string() | +| 27th June 2026 | [Diagnosticism.Rust 0.2.1](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.2.1) released | CI tasks and Clippy fixes | +| 24th July 2025 | [Diagnosticism.Rust 0.2.0](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.2.0) released | Added doom_scope<>() | +| 29th March 2025 | [Diagnosticism.Rust 0.1.0](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.1.0) released | File/line/function macros | +| 19th December 2024 | [Diagnosticism.Rust 0.0.2](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.0.2) released | Added DoomGram | +| 13th September 2024 | [Diagnosticism.Rust 0.0.1](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.0.1) released | DebugSqueezer, Ellipsis, Password | +| 27th August 2024 | [Diagnosticism.Rust 0.0.0](https://github.com/synesissoftware/Diagnosticism.Rust/releases/tag/0.0.0) released | Initial empty version | diff --git a/README.md b/README.md index 3e6c495..dc0f0b9 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ Other facilities (that are not directly related to `Debug`) will be added to the - [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) - [Dev Dependencies](#dev-dependencies) - [Related projects](#related-projects) @@ -332,6 +333,15 @@ Terse `Debug` form of `thing2`: Thing2 { name: "i-am-a-public-thing", internals: Defect reports, feature requests, and pull requests are welcome on https://github.com/synesissoftware/Diagnosticism.Rust. +### Minimum Supported Rust Version (MSRV) + +The declared Minimum Supported Rust Version (MSRV) for **Diagnosticism.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 * [**base-traits**](https://github.com/synesissoftware/base-traits.rs); diff --git a/TODO.md b/TODO.md index 0145aa3..ba8bfcd 100644 --- a/TODO.md +++ b/TODO.md @@ -1,17 +1,19 @@ # Diagnosticism.Rust - TODO + ## Table of Contents - [Functional improvements](#functional-improvements) - [Performance improvements](#performance-improvements) +- [Packaging improvements](#packaging-improvements) ## Functional improvements -* [x] ~~~simple file/line/function macros~~~: - * [x] `fileline!()`; - * [x] `function!()`; - * [x] `filelinefunction!()`; +* [x] ~~~simple file/line/function macros~~~ - ✅: + * [x] ~~~`fileline!()`~~~ - ✅; + * [x] ~~~`function!()`~~~ - ✅; + * [x] ~~~`filelinefunction!()`~~~ - ✅; * [ ] advanced file/line/function macros, using procedural macros, such that, say, `function!()` acts as a literal (and can participate in `concat!()`); @@ -22,5 +24,9 @@ * [ ] Determine whether use of `ilog10()` can help to reduce performance costs of `DoomGram`; - +## 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 af3938f..6ff4572 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,17 +1,16 @@ - -# rustfmt.toml for Diagnosticism.Rust -# -# Requires pinned nightly rustfmt with unstable features enabled, e.g.: +# rustfmt.toml # -# ./scripts/fmt +# Synesis Information Systems — gold rustfmt configuration for SIS Rust +# crates. # -# Or: +# Requires pinned nightly rustfmt with unstable features. Prefer: # -# cargo +nightly-2026-08-08 fmt -- --unstable-features +# ./scripts/fmt # -# The wrapper uses nightly-2026-08-08 by default. +# Default pin (see scripts/fmt): nightly-2026-09-10 # -# configured for cargo-fmt 1.99.0-nightly +# 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 @@ -31,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 @@ -45,7 +44,6 @@ group_imports="Preserve" hard_tabs=false # hide_parse_errors=false ignore=[ - ] imports_granularity="Crate" imports_indent="Block" @@ -70,6 +68,7 @@ reorder_modules=true # report_fixme="Always" # report_todo="Never" # required_version="????" +short_array_element_width_threshold=1 show_parse_errors=true # single_line_if_else_max_width=0 # deprecated skip_children=false @@ -78,9 +77,12 @@ space_before_colon=true spaces_around_ranges=false struct_field_align_threshold=20 struct_lit_single_line=false +# struct_lit_trailing_comma="Vertical" # struct_lit_width=0 # deprecated +# struct_trailing_comma="Vertical" # struct_variant_width=0 # deprecated -tab_spaces=4 # Q: do we want to move to 2?? +# style_edition="2021" +tab_spaces=4 trailing_comma="Vertical" trailing_semicolon=true type_punctuation_density="Wide" @@ -91,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 dc0f30d..5c595ec 100755 --- a/scripts/check_derives.py +++ b/scripts/check_derives.py @@ -101,7 +101,7 @@ def main() -> int: root = Path(__file__).resolve().parents[1] errors: list[str] = [] - for directory in ("src", "examples", "benches"): + for directory in ("src", "examples", "benches", "test"): base = root / directory if not base.is_dir(): diff --git a/scripts/check_test_names.py b/scripts/check_test_names.py index f91c003..1909373 100755 --- a/scripts/check_test_names.py +++ b/scripts/check_test_names.py @@ -1,8 +1,12 @@ -#!/usr/bin/env python3 +#! /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 (type, function, macro, field, etc.) which must preserve exact case. + +When a construct name is embedded as a SHOUTING_SNAKE_CASE constant (or +PascalCase construct), it may be delimited with an extra underscore on +each side — e.g. HAVING__IGNORE_CASE__1. """ from __future__ import annotations @@ -16,7 +20,6 @@ FN_DEF = re.compile(r"^\s*fn\s+(\w+)") MOD_DEF = re.compile(r"^\s*mod\s+(\w+)") SNAKE_PART = re.compile(r"^[a-z][a-z0-9]*$") -CONSECUTIVE_UPPER = re.compile(r"[A-Z]{2,}") PASS = "\N{WHITE HEAVY CHECK MARK}" # ✅ FAIL = "\N{CROSS MARK}" # ❌ @@ -26,7 +29,6 @@ def is_pascal_case_atom(atom: str) -> bool: return ( atom[0].isupper() and any(c.islower() for c in atom) - and not CONSECUTIVE_UPPER.search(atom) and atom.isalnum() ) @@ -42,11 +44,53 @@ def atom_violation(atom: str) -> str | None: return None return ( - f"segment '{atom}' must be SHOUTING_SNAKE_CASE, a PascalCase construct name, " - "or a Rust snake_case identifier" + f"segment '{atom}' must be SHOUTING_SNAKE_CASE, a PascalCase construct " + "name, or a Rust snake_case identifier" ) +def parse_padded_construct( + segments: list[str], start: int +) -> tuple[str | None, int, list[str]]: + """Parse __CONSTRUCT__ padding around a shouting or PascalCase atom.""" + violations: list[str] = [] + i = start + + while i < len(segments) and not segments[i]: + i += 1 + if i >= len(segments): + return None, i, ["empty segment padding without construct"] + + seg = segments[i] + atom: str | None = None + + if seg.isupper() or seg.isdigit(): + parts = [seg] + i += 1 + while i < len(segments) and segments[i] and ( + segments[i].isupper() or segments[i].isdigit() + ): + parts.append(segments[i]) + i += 1 + atom = "_".join(parts) + reason = atom_violation(atom) + if reason: + violations.append(reason) + elif seg[0].isupper() and is_pascal_case_atom(seg): + atom = seg + reason = atom_violation(seg) + if reason: + violations.append(reason) + i += 1 + else: + return None, start, ["empty segment padding without construct"] + + while i < len(segments) and not segments[i]: + i += 1 + + return atom, i, violations + + def parse_name_atoms(rest: str) -> tuple[list[str], list[str]]: """Split a test name body into atoms; return (atoms, violations).""" atoms: list[str] = [] @@ -57,8 +101,15 @@ def parse_name_atoms(rest: str) -> tuple[list[str], list[str]]: while i < len(segments): seg = segments[i] if not seg: - violations.append(f"empty segment in '{rest}'") - i += 1 + start = i + atom, i, viols = parse_padded_construct(segments, i) + violations.extend(viols) + if atom: + atoms.append(atom) + elif not viols: + violations.append(f"empty segment in '{rest}'") + if i == start: + i += 1 continue if seg.isupper() or seg.isdigit(): @@ -94,8 +145,8 @@ def parse_name_atoms(rest: str) -> tuple[list[str], list[str]]: continue violations.append( - f"segment '{seg}' must be SHOUTING_SNAKE_CASE, a PascalCase construct name, " - "or a Rust snake_case identifier" + f"segment '{seg}' must be SHOUTING_SNAKE_CASE, a PascalCase construct " + "name, or a Rust snake_case identifier" ) i += 1 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/macros.rs b/src/macros.rs index 96501c1..fdaa837 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -33,8 +33,7 @@ macro_rules! declare_and_publish_impl_ { /// * `declare_and_publish!(crate mod_name, Item)` — `pub(crate) use`; /// * `declare_and_publish!(super mod_name, Item)` — `pub(super) use`; /// * `declare_and_publish!(self mod_name, Item)` — `pub(self) use`; -/// * `declare_and_publish!(priv mod_name, Item)` — `pub(self) use` -/// (synonym); +/// * `declare_and_publish!(priv mod_name, Item)` — `pub(self) use` (syn.); /// * `declare_and_publish!($vis mod_name, Item)` — any Rust visibility /// (e.g. `pub(crate)`, `pub(in crate::api)`). ///