max / makenotwork
15 files changed,
+79 insertions,
-103 deletions
| @@ -0,0 +1,4 @@ | |||
| 1 | + | [toolchain] | |
| 2 | + | channel = "stable" | |
| 3 | + | profile = "minimal" | |
| 4 | + | components = ["rustfmt", "clippy"] |
| @@ -51,24 +51,24 @@ pedantic = { level = "warn", priority = -1 } | |||
| 51 | 51 | # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything | |
| 52 | 52 | # else in `pedantic` stays a warning. Keep this block identical across repos. | |
| 53 | 53 | module_name_repetitions = "allow" | |
| 54 | - | # Doc lints — no docs-completeness push underway. | |
| 54 | + | # Doc lints. No docs-completeness push is underway. | |
| 55 | 55 | missing_errors_doc = "allow" | |
| 56 | 56 | missing_panics_doc = "allow" | |
| 57 | 57 | doc_markdown = "allow" | |
| 58 | - | # Numeric casts — endemic and mostly intentional in size/byte math. | |
| 58 | + | # Numeric casts. Endemic and mostly intentional in size and byte math. | |
| 59 | 59 | cast_possible_truncation = "allow" | |
| 60 | 60 | cast_sign_loss = "allow" | |
| 61 | 61 | cast_precision_loss = "allow" | |
| 62 | 62 | cast_possible_wrap = "allow" | |
| 63 | 63 | cast_lossless = "allow" | |
| 64 | - | # Subjective structure/style nags — high churn, low signal. | |
| 64 | + | # Subjective structure and style nags. High churn, low signal. | |
| 65 | 65 | must_use_candidate = "allow" | |
| 66 | 66 | too_many_lines = "allow" | |
| 67 | 67 | struct_excessive_bools = "allow" | |
| 68 | 68 | similar_names = "allow" | |
| 69 | 69 | items_after_statements = "allow" | |
| 70 | 70 | single_match_else = "allow" | |
| 71 | - | # Frequent false-positives in TUI/router-heavy code — added from the buckets breakdown. | |
| 71 | + | # Frequent false-positives in TUI and router-heavy code. | |
| 72 | 72 | match_same_arms = "allow" | |
| 73 | 73 | unnecessary_wraps = "allow" | |
| 74 | 74 | type_complexity = "allow" |
| @@ -22,24 +22,24 @@ pedantic = { level = "warn", priority = -1 } | |||
| 22 | 22 | # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything | |
| 23 | 23 | # else in `pedantic` stays a warning. Keep this block identical across repos. | |
| 24 | 24 | module_name_repetitions = "allow" | |
| 25 | - | # Doc lints — no docs-completeness push underway. | |
| 25 | + | # Doc lints. No docs-completeness push is underway. | |
| 26 | 26 | missing_errors_doc = "allow" | |
| 27 | 27 | missing_panics_doc = "allow" | |
| 28 | 28 | doc_markdown = "allow" | |
| 29 | - | # Numeric casts — endemic and mostly intentional in size/byte math. | |
| 29 | + | # Numeric casts. Endemic and mostly intentional in size and byte math. | |
| 30 | 30 | cast_possible_truncation = "allow" | |
| 31 | 31 | cast_sign_loss = "allow" | |
| 32 | 32 | cast_precision_loss = "allow" | |
| 33 | 33 | cast_possible_wrap = "allow" | |
| 34 | 34 | cast_lossless = "allow" | |
| 35 | - | # Subjective structure/style nags — high churn, low signal. | |
| 35 | + | # Subjective structure and style nags. High churn, low signal. | |
| 36 | 36 | must_use_candidate = "allow" | |
| 37 | 37 | too_many_lines = "allow" | |
| 38 | 38 | struct_excessive_bools = "allow" | |
| 39 | 39 | similar_names = "allow" | |
| 40 | 40 | items_after_statements = "allow" | |
| 41 | 41 | single_match_else = "allow" | |
| 42 | - | # Frequent false-positives in TUI/router-heavy code — added from the buckets breakdown. | |
| 42 | + | # Frequent false-positives in TUI and router-heavy code. | |
| 43 | 43 | match_same_arms = "allow" | |
| 44 | 44 | unnecessary_wraps = "allow" | |
| 45 | 45 | type_complexity = "allow" |
| @@ -45,24 +45,24 @@ pedantic = { level = "warn", priority = -1 } | |||
| 45 | 45 | # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything | |
| 46 | 46 | # else in `pedantic` stays a warning. Keep this block identical across repos. | |
| 47 | 47 | module_name_repetitions = "allow" | |
| 48 | - | # Doc lints — no docs-completeness push underway. | |
| 48 | + | # Doc lints. No docs-completeness push is underway. | |
| 49 | 49 | missing_errors_doc = "allow" | |
| 50 | 50 | missing_panics_doc = "allow" | |
| 51 | 51 | doc_markdown = "allow" | |
| 52 | - | # Numeric casts — endemic and mostly intentional in size/byte math. | |
| 52 | + | # Numeric casts. Endemic and mostly intentional in size and byte math. | |
| 53 | 53 | cast_possible_truncation = "allow" | |
| 54 | 54 | cast_sign_loss = "allow" | |
| 55 | 55 | cast_precision_loss = "allow" | |
| 56 | 56 | cast_possible_wrap = "allow" | |
| 57 | 57 | cast_lossless = "allow" | |
| 58 | - | # Subjective structure/style nags — high churn, low signal. | |
| 58 | + | # Subjective structure and style nags. High churn, low signal. | |
| 59 | 59 | must_use_candidate = "allow" | |
| 60 | 60 | too_many_lines = "allow" | |
| 61 | 61 | struct_excessive_bools = "allow" | |
| 62 | 62 | similar_names = "allow" | |
| 63 | 63 | items_after_statements = "allow" | |
| 64 | 64 | single_match_else = "allow" | |
| 65 | - | # Frequent false-positives in TUI/router-heavy code — added from the buckets breakdown. | |
| 65 | + | # Frequent false-positives in TUI and router-heavy code. | |
| 66 | 66 | match_same_arms = "allow" | |
| 67 | 67 | unnecessary_wraps = "allow" | |
| 68 | 68 | type_complexity = "allow" |
| @@ -37,24 +37,24 @@ pedantic = { level = "warn", priority = -1 } | |||
| 37 | 37 | # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything | |
| 38 | 38 | # else in `pedantic` stays a warning. Keep this block identical across repos. | |
| 39 | 39 | module_name_repetitions = "allow" | |
| 40 | - | # Doc lints — no docs-completeness push underway. | |
| 40 | + | # Doc lints. No docs-completeness push is underway. | |
| 41 | 41 | missing_errors_doc = "allow" | |
| 42 | 42 | missing_panics_doc = "allow" | |
| 43 | 43 | doc_markdown = "allow" | |
| 44 | - | # Numeric casts — endemic and mostly intentional in size/byte math. | |
| 44 | + | # Numeric casts. Endemic and mostly intentional in size and byte math. | |
| 45 | 45 | cast_possible_truncation = "allow" | |
| 46 | 46 | cast_sign_loss = "allow" | |
| 47 | 47 | cast_precision_loss = "allow" | |
| 48 | 48 | cast_possible_wrap = "allow" | |
| 49 | 49 | cast_lossless = "allow" | |
| 50 | - | # Subjective structure/style nags — high churn, low signal. | |
| 50 | + | # Subjective structure and style nags. High churn, low signal. | |
| 51 | 51 | must_use_candidate = "allow" | |
| 52 | 52 | too_many_lines = "allow" | |
| 53 | 53 | struct_excessive_bools = "allow" | |
| 54 | 54 | similar_names = "allow" | |
| 55 | 55 | items_after_statements = "allow" | |
| 56 | 56 | single_match_else = "allow" | |
| 57 | - | # Frequent false-positives in TUI/router-heavy code — added from the buckets breakdown. | |
| 57 | + | # Frequent false-positives in TUI and router-heavy code. | |
| 58 | 58 | match_same_arms = "allow" | |
| 59 | 59 | unnecessary_wraps = "allow" | |
| 60 | 60 | type_complexity = "allow" |
| @@ -29,24 +29,24 @@ pedantic = { level = "warn", priority = -1 } | |||
| 29 | 29 | # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything | |
| 30 | 30 | # else in `pedantic` stays a warning. Keep this block identical across repos. | |
| 31 | 31 | module_name_repetitions = "allow" | |
| 32 | - | # Doc lints — no docs-completeness push underway. | |
| 32 | + | # Doc lints. No docs-completeness push is underway. | |
| 33 | 33 | missing_errors_doc = "allow" | |
| 34 | 34 | missing_panics_doc = "allow" | |
| 35 | 35 | doc_markdown = "allow" | |
| 36 | - | # Numeric casts — endemic and mostly intentional in size/byte math. | |
| 36 | + | # Numeric casts. Endemic and mostly intentional in size and byte math. | |
| 37 | 37 | cast_possible_truncation = "allow" | |
| 38 | 38 | cast_sign_loss = "allow" | |
| 39 | 39 | cast_precision_loss = "allow" | |
| 40 | 40 | cast_possible_wrap = "allow" | |
| 41 | 41 | cast_lossless = "allow" | |
| 42 | - | # Subjective structure/style nags — high churn, low signal. | |
| 42 | + | # Subjective structure and style nags. High churn, low signal. | |
| 43 | 43 | must_use_candidate = "allow" | |
| 44 | 44 | too_many_lines = "allow" | |
| 45 | 45 | struct_excessive_bools = "allow" | |
| 46 | 46 | similar_names = "allow" | |
| 47 | 47 | items_after_statements = "allow" | |
| 48 | 48 | single_match_else = "allow" | |
| 49 | - | # Frequent false-positives in TUI/router-heavy code — added from the buckets breakdown. | |
| 49 | + | # Frequent false-positives in TUI and router-heavy code. | |
| 50 | 50 | match_same_arms = "allow" | |
| 51 | 51 | unnecessary_wraps = "allow" | |
| 52 | 52 | type_complexity = "allow" |
| @@ -49,24 +49,24 @@ pedantic = { level = "warn", priority = -1 } | |||
| 49 | 49 | # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything | |
| 50 | 50 | # else in `pedantic` stays a warning. Keep this block identical across repos. | |
| 51 | 51 | module_name_repetitions = "allow" | |
| 52 | - | # Doc lints — no docs-completeness push underway. | |
| 52 | + | # Doc lints. No docs-completeness push is underway. | |
| 53 | 53 | missing_errors_doc = "allow" | |
| 54 | 54 | missing_panics_doc = "allow" | |
| 55 | 55 | doc_markdown = "allow" | |
| 56 | - | # Numeric casts — endemic and mostly intentional in size/byte math. | |
| 56 | + | # Numeric casts. Endemic and mostly intentional in size and byte math. | |
| 57 | 57 | cast_possible_truncation = "allow" | |
| 58 | 58 | cast_sign_loss = "allow" | |
| 59 | 59 | cast_precision_loss = "allow" | |
| 60 | 60 | cast_possible_wrap = "allow" | |
| 61 | 61 | cast_lossless = "allow" | |
| 62 | - | # Subjective structure/style nags — high churn, low signal. | |
| 62 | + | # Subjective structure and style nags. High churn, low signal. | |
| 63 | 63 | must_use_candidate = "allow" | |
| 64 | 64 | too_many_lines = "allow" | |
| 65 | 65 | struct_excessive_bools = "allow" | |
| 66 | 66 | similar_names = "allow" | |
| 67 | 67 | items_after_statements = "allow" | |
| 68 | 68 | single_match_else = "allow" | |
| 69 | - | # Frequent false-positives in TUI/router-heavy code — added from the buckets breakdown. | |
| 69 | + | # Frequent false-positives in TUI and router-heavy code. | |
| 70 | 70 | match_same_arms = "allow" | |
| 71 | 71 | unnecessary_wraps = "allow" | |
| 72 | 72 | type_complexity = "allow" |
| @@ -20,24 +20,24 @@ pedantic = { level = "warn", priority = -1 } | |||
| 20 | 20 | # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything | |
| 21 | 21 | # else in `pedantic` stays a warning. Keep this block identical across repos. | |
| 22 | 22 | module_name_repetitions = "allow" | |
| 23 | - | # Doc lints — no docs-completeness push underway. | |
| 23 | + | # Doc lints. No docs-completeness push is underway. | |
| 24 | 24 | missing_errors_doc = "allow" | |
| 25 | 25 | missing_panics_doc = "allow" | |
| 26 | 26 | doc_markdown = "allow" | |
| 27 | - | # Numeric casts — endemic and mostly intentional in size/byte math. | |
| 27 | + | # Numeric casts. Endemic and mostly intentional in size and byte math. | |
| 28 | 28 | cast_possible_truncation = "allow" | |
| 29 | 29 | cast_sign_loss = "allow" | |
| 30 | 30 | cast_precision_loss = "allow" | |
| 31 | 31 | cast_possible_wrap = "allow" | |
| 32 | 32 | cast_lossless = "allow" | |
| 33 | - | # Subjective structure/style nags — high churn, low signal. | |
| 33 | + | # Subjective structure and style nags. High churn, low signal. | |
| 34 | 34 | must_use_candidate = "allow" | |
| 35 | 35 | too_many_lines = "allow" | |
| 36 | 36 | struct_excessive_bools = "allow" | |
| 37 | 37 | similar_names = "allow" | |
| 38 | 38 | items_after_statements = "allow" | |
| 39 | 39 | single_match_else = "allow" | |
| 40 | - | # Frequent false-positives in TUI/router-heavy code — added from the buckets breakdown. | |
| 40 | + | # Frequent false-positives in TUI and router-heavy code. | |
| 41 | 41 | match_same_arms = "allow" | |
| 42 | 42 | unnecessary_wraps = "allow" | |
| 43 | 43 | type_complexity = "allow" |
| @@ -19,24 +19,24 @@ pedantic = { level = "warn", priority = -1 } | |||
| 19 | 19 | # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything | |
| 20 | 20 | # else in `pedantic` stays a warning. Keep this block identical across repos. | |
| 21 | 21 | module_name_repetitions = "allow" | |
| 22 | - | # Doc lints — no docs-completeness push underway. | |
| 22 | + | # Doc lints. No docs-completeness push is underway. | |
| 23 | 23 | missing_errors_doc = "allow" | |
| 24 | 24 | missing_panics_doc = "allow" | |
| 25 | 25 | doc_markdown = "allow" | |
| 26 | - | # Numeric casts — endemic and mostly intentional in size/byte math. | |
| 26 | + | # Numeric casts. Endemic and mostly intentional in size and byte math. | |
| 27 | 27 | cast_possible_truncation = "allow" | |
| 28 | 28 | cast_sign_loss = "allow" | |
| 29 | 29 | cast_precision_loss = "allow" | |
| 30 | 30 | cast_possible_wrap = "allow" | |
| 31 | 31 | cast_lossless = "allow" | |
| 32 | - | # Subjective structure/style nags — high churn, low signal. | |
| 32 | + | # Subjective structure and style nags. High churn, low signal. | |
| 33 | 33 | must_use_candidate = "allow" | |
| 34 | 34 | too_many_lines = "allow" | |
| 35 | 35 | struct_excessive_bools = "allow" | |
| 36 | 36 | similar_names = "allow" | |
| 37 | 37 | items_after_statements = "allow" | |
| 38 | 38 | single_match_else = "allow" | |
| 39 | - | # Frequent false-positives in TUI/router-heavy code — added from the buckets breakdown. | |
| 39 | + | # Frequent false-positives in TUI and router-heavy code. | |
| 40 | 40 | match_same_arms = "allow" | |
| 41 | 41 | unnecessary_wraps = "allow" | |
| 42 | 42 | type_complexity = "allow" |
| @@ -24,24 +24,24 @@ pedantic = { level = "warn", priority = -1 } | |||
| 24 | 24 | # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything | |
| 25 | 25 | # else in `pedantic` stays a warning. Keep this block identical across repos. | |
| 26 | 26 | module_name_repetitions = "allow" | |
| 27 | - | # Doc lints — no docs-completeness push underway. | |
| 27 | + | # Doc lints. No docs-completeness push is underway. | |
| 28 | 28 | missing_errors_doc = "allow" | |
| 29 | 29 | missing_panics_doc = "allow" | |
| 30 | 30 | doc_markdown = "allow" | |
| 31 | - | # Numeric casts — endemic and mostly intentional in size/byte math. | |
| 31 | + | # Numeric casts. Endemic and mostly intentional in size and byte math. | |
| 32 | 32 | cast_possible_truncation = "allow" | |
| 33 | 33 | cast_sign_loss = "allow" | |
| 34 | 34 | cast_precision_loss = "allow" | |
| 35 | 35 | cast_possible_wrap = "allow" | |
| 36 | 36 | cast_lossless = "allow" | |
| 37 | - | # Subjective structure/style nags — high churn, low signal. | |
| 37 | + | # Subjective structure and style nags. High churn, low signal. | |
| 38 | 38 | must_use_candidate = "allow" | |
| 39 | 39 | too_many_lines = "allow" | |
| 40 | 40 | struct_excessive_bools = "allow" | |
| 41 | 41 | similar_names = "allow" | |
| 42 | 42 | items_after_statements = "allow" | |
| 43 | 43 | single_match_else = "allow" | |
| 44 | - | # Frequent false-positives in TUI/router-heavy code — added from the buckets breakdown. | |
| 44 | + | # Frequent false-positives in TUI and router-heavy code. | |
| 45 | 45 | match_same_arms = "allow" | |
| 46 | 46 | unnecessary_wraps = "allow" | |
| 47 | 47 | type_complexity = "allow" |
| @@ -27,24 +27,24 @@ pedantic = { level = "warn", priority = -1 } | |||
| 27 | 27 | # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything | |
| 28 | 28 | # else in `pedantic` stays a warning. Keep this block identical across repos. | |
| 29 | 29 | module_name_repetitions = "allow" | |
| 30 | - | # Doc lints — no docs-completeness push underway. | |
| 30 | + | # Doc lints. No docs-completeness push is underway. | |
| 31 | 31 | missing_errors_doc = "allow" | |
| 32 | 32 | missing_panics_doc = "allow" | |
| 33 | 33 | doc_markdown = "allow" | |
| 34 | - | # Numeric casts — endemic and mostly intentional in size/byte math. | |
| 34 | + | # Numeric casts. Endemic and mostly intentional in size and byte math. | |
| 35 | 35 | cast_possible_truncation = "allow" | |
| 36 | 36 | cast_sign_loss = "allow" | |
| 37 | 37 | cast_precision_loss = "allow" | |
| 38 | 38 | cast_possible_wrap = "allow" | |
| 39 | 39 | cast_lossless = "allow" | |
| 40 | - | # Subjective structure/style nags — high churn, low signal. | |
| 40 | + | # Subjective structure and style nags. High churn, low signal. | |
| 41 | 41 | must_use_candidate = "allow" | |
| 42 | 42 | too_many_lines = "allow" | |
| 43 | 43 | struct_excessive_bools = "allow" | |
| 44 | 44 | similar_names = "allow" | |
| 45 | 45 | items_after_statements = "allow" | |
| 46 | 46 | single_match_else = "allow" | |
| 47 | - | # Frequent false-positives in TUI/router-heavy code across the ecosystem. | |
| 47 | + | # Frequent false-positives in TUI and router-heavy code. | |
| 48 | 48 | match_same_arms = "allow" | |
| 49 | 49 | unnecessary_wraps = "allow" | |
| 50 | 50 | type_complexity = "allow" |
| @@ -212,9 +212,7 @@ fn bench_tag_index(c: &mut Criterion) { | |||
| 212 | 212 | group.finish(); | |
| 213 | 213 | } | |
| 214 | 214 | ||
| 215 | - | // --------------------------------------------------------------------------- | |
| 216 | 215 | // Large-scale benchmarks (1K, 10K, 50K tags) | |
| 217 | - | // --------------------------------------------------------------------------- | |
| 218 | 216 | ||
| 219 | 217 | /// Generate a hierarchical tag set of approximately `target` tags. | |
| 220 | 218 | /// | |
| @@ -272,7 +270,7 @@ fn bench_large_tree_ops(c: &mut Criterion) { | |||
| 272 | 270 | ||
| 273 | 271 | let mut group = c.benchmark_group("large_tree_ops"); | |
| 274 | 272 | ||
| 275 | - | // children_at_prefix — scans the full tag list | |
| 273 | + | // children_at_prefix: scans the full tag list | |
| 276 | 274 | group.bench_function("children_at_prefix/1k", |b| { | |
| 277 | 275 | b.iter(|| tagtree::children_at_prefix(black_box("genre"), &tags_1k)); | |
| 278 | 276 | }); | |
| @@ -283,7 +281,7 @@ fn bench_large_tree_ops(c: &mut Criterion) { | |||
| 283 | 281 | b.iter(|| tagtree::children_at_prefix(black_box("genre"), &tags_50k)); | |
| 284 | 282 | }); | |
| 285 | 283 | ||
| 286 | - | // subtree — scans for prefix matches | |
| 284 | + | // subtree: scans for prefix matches | |
| 287 | 285 | group.bench_function("subtree/1k", |b| { | |
| 288 | 286 | b.iter(|| tagtree::subtree(black_box("genre"), &tags_1k)); | |
| 289 | 287 | }); | |
| @@ -315,7 +313,7 @@ fn bench_large_tag_index(c: &mut Criterion) { | |||
| 315 | 313 | b.iter(|| TagIndex::new(black_box(tags_50k.clone()))); | |
| 316 | 314 | }); | |
| 317 | 315 | ||
| 318 | - | // Suggest — build once, query many | |
| 316 | + | // Suggest: build once, query many | |
| 319 | 317 | let idx_1k = TagIndex::new(tags_1k); | |
| 320 | 318 | let idx_10k = TagIndex::new(tags_10k); | |
| 321 | 319 | let idx_50k = TagIndex::new(tags_50k); | |
| @@ -376,9 +374,7 @@ fn bench_large_validate(c: &mut Criterion) { | |||
| 376 | 374 | group.finish(); | |
| 377 | 375 | } | |
| 378 | 376 | ||
| 379 | - | // --------------------------------------------------------------------------- | |
| 380 | 377 | // Deep tree benchmarks (max depth stress test) | |
| 381 | - | // --------------------------------------------------------------------------- | |
| 382 | 378 | ||
| 383 | 379 | /// Generate a single tag chain of depth `n`: "a.b.c.d.e.f..." | |
| 384 | 380 | fn deep_tag(depth: usize) -> String { |
| @@ -46,9 +46,7 @@ const SEPARATOR_BYTE: u8 = { | |||
| 46 | 46 | SEPARATOR as u8 | |
| 47 | 47 | }; | |
| 48 | 48 | ||
| 49 | - | // --------------------------------------------------------------------------- | |
| 50 | 49 | // Configuration | |
| 51 | - | // --------------------------------------------------------------------------- | |
| 52 | 50 | ||
| 53 | 51 | /// Per-app tag rules. Each consumer defines one of these as a constant. | |
| 54 | 52 | /// | |
| @@ -127,9 +125,7 @@ impl fmt::Display for TagError { | |||
| 127 | 125 | ||
| 128 | 126 | impl std::error::Error for TagError {} | |
| 129 | 127 | ||
| 130 | - | // --------------------------------------------------------------------------- | |
| 131 | 128 | // Validation | |
| 132 | - | // --------------------------------------------------------------------------- | |
| 133 | 129 | ||
| 134 | 130 | /// Validate a tag against an app-specific [`TagConfig`]. | |
| 135 | 131 | /// | |
| @@ -203,9 +199,7 @@ pub fn validate(tag: &str) -> Result<(), TagError> { | |||
| 203 | 199 | validate_with(tag, &DEFAULT) | |
| 204 | 200 | } | |
| 205 | 201 | ||
| 206 | - | // --------------------------------------------------------------------------- | |
| 207 | 202 | // Hierarchy parsing | |
| 208 | - | // --------------------------------------------------------------------------- | |
| 209 | 203 | ||
| 210 | 204 | /// Get the parent path of a tag, or `None` if it's a root-level tag. | |
| 211 | 205 | /// | |
| @@ -353,9 +347,7 @@ pub fn common_ancestor<'a>(a: &'a str, b: &str) -> Option<&'a str> { | |||
| 353 | 347 | last_sep.map(|pos| &a[..pos]) | |
| 354 | 348 | } | |
| 355 | 349 | ||
| 356 | - | // --------------------------------------------------------------------------- | |
| 357 | 350 | // Semantic prefix helpers | |
| 358 | - | // --------------------------------------------------------------------------- | |
| 359 | 351 | ||
| 360 | 352 | /// Extract the semantic prefix (first `n` segments) from a tag. | |
| 361 | 353 | /// | |
| @@ -413,9 +405,7 @@ pub fn free_suffix(tag: &str, semantic_depth: usize) -> Option<&str> { | |||
| 413 | 405 | } | |
| 414 | 406 | } | |
| 415 | 407 | ||
| 416 | - | // --------------------------------------------------------------------------- | |
| 417 | 408 | // Tree operations on tag sets (in-memory) | |
| 418 | - | // --------------------------------------------------------------------------- | |
| 419 | 409 | ||
| 420 | 410 | /// List the immediate child segment names under a prefix. | |
| 421 | 411 | /// | |
| @@ -489,9 +479,7 @@ pub fn subtree<'a>(prefix: &str, tags: &'a [impl AsRef<str>]) -> Vec<&'a str> { | |||
| 489 | 479 | .collect() | |
| 490 | 480 | } | |
| 491 | 481 | ||
| 492 | - | // --------------------------------------------------------------------------- | |
| 493 | 482 | // SQL helpers | |
| 494 | - | // --------------------------------------------------------------------------- | |
| 495 | 483 | ||
| 496 | 484 | /// Escape special characters in a string for use in SQL `LIKE` patterns. | |
| 497 | 485 | /// | |
| @@ -522,9 +510,7 @@ pub fn like_descendant_pattern(prefix: &str) -> String { | |||
| 522 | 510 | format!("{}.%", escape_like(prefix)) | |
| 523 | 511 | } | |
| 524 | 512 | ||
| 525 | - | // --------------------------------------------------------------------------- | |
| 526 | 513 | // Rename / move | |
| 527 | - | // --------------------------------------------------------------------------- | |
| 528 | 514 | ||
| 529 | 515 | /// Rename a prefix within a tag. Returns `Some(new_tag)` if the tag starts with | |
| 530 | 516 | /// `old_prefix` at a segment boundary, or `None` if it doesn't match. | |
| @@ -551,9 +537,7 @@ pub fn rename_prefix(old_prefix: &str, new_prefix: &str, tag: &str) -> Option<St | |||
| 551 | 537 | } | |
| 552 | 538 | } | |
| 553 | 539 | ||
| 554 | - | // --------------------------------------------------------------------------- | |
| 555 | 540 | // Edit distance (private) | |
| 556 | - | // --------------------------------------------------------------------------- | |
| 557 | 541 | ||
| 558 | 542 | /// Levenshtein distance with early termination. Returns `None` if the distance | |
| 559 | 543 | /// exceeds `max`. Uses single-row DP (O(min(m,n)) space). | |
| @@ -590,9 +574,7 @@ pub fn tagtree_test_dist(a: &str, b: &str) -> Option<usize> { | |||
| 590 | 574 | edit_distance(a, b, 2) | |
| 591 | 575 | } | |
| 592 | 576 | ||
| 593 | - | // --------------------------------------------------------------------------- | |
| 594 | 577 | // Bulk tag operations | |
| 595 | - | // --------------------------------------------------------------------------- | |
| 596 | 578 | ||
| 597 | 579 | /// Rename a prefix across all tags in an index. Returns the number of tags modified. | |
| 598 | 580 | /// | |
| @@ -714,9 +696,7 @@ pub fn batch_rename(operations: &[(&str, &str)], index: &mut TagIndex) -> usize | |||
| 714 | 696 | total | |
| 715 | 697 | } | |
| 716 | 698 | ||
| 717 | - | // --------------------------------------------------------------------------- | |
| 718 | 699 | // In-memory suggestion index | |
| 719 | - | // --------------------------------------------------------------------------- | |
| 720 | 700 | ||
| 721 | 701 | /// In-memory tag index for keystroke-speed autocomplete. | |
| 722 | 702 | /// | |
| @@ -998,9 +978,7 @@ impl Default for TagIndex { | |||
| 998 | 978 | } | |
| 999 | 979 | } | |
| 1000 | 980 | ||
| 1001 | - | // --------------------------------------------------------------------------- | |
| 1002 | 981 | // Tests | |
| 1003 | - | // --------------------------------------------------------------------------- | |
| 1004 | 982 | ||
| 1005 | 983 | #[cfg(test)] | |
| 1006 | 984 | mod tests { | |
| @@ -1211,7 +1189,7 @@ mod tests { | |||
| 1211 | 1189 | ||
| 1212 | 1190 | #[test] | |
| 1213 | 1191 | fn free_suffix_at_boundary() { | |
| 1214 | - | // Tag is exactly the semantic prefix length — no suffix | |
| 1192 | + | // Tag is exactly the semantic prefix length, no suffix | |
| 1215 | 1193 | assert_eq!(free_suffix("genre", 1), None); | |
| 1216 | 1194 | assert_eq!(free_suffix("type.audio", 2), None); | |
| 1217 | 1195 | } | |
| @@ -1657,7 +1635,7 @@ mod tests { | |||
| 1657 | 1635 | #[test] | |
| 1658 | 1636 | fn suggest_exact_tag() { | |
| 1659 | 1637 | let idx = test_index(); | |
| 1660 | - | // "mood.dark" is an exact tag — should still appear | |
| 1638 | + | // "mood.dark" is an exact tag, should still appear | |
| 1661 | 1639 | assert_eq!(idx.suggest("mood.dark", 10), vec!["mood.dark"]); | |
| 1662 | 1640 | } | |
| 1663 | 1641 | ||
| @@ -1703,8 +1681,8 @@ mod tests { | |||
| 1703 | 1681 | fn suggest_segment_prefix_finds_multiple() { | |
| 1704 | 1682 | let idx = test_index(); | |
| 1705 | 1683 | // "drum" matches instrument.drum.kick and instrument.drum.snare via segment | |
| 1706 | - | // But it also matches as a path prefix of "instrument.drum" — wait, no. | |
| 1707 | - | // "drum" as path prefix: tags starting with "drum" — none. | |
| 1684 | + | // But it also matches as a path prefix of "instrument.drum", wait, no. | |
| 1685 | + | // "drum" as path prefix: tags starting with "drum": none. | |
| 1708 | 1686 | // "drum" as segment prefix: "instrument.drum.kick" has segment "drum". | |
| 1709 | 1687 | assert_eq!( | |
| 1710 | 1688 | idx.suggest("drum", 10), | |
| @@ -1722,7 +1700,7 @@ mod tests { | |||
| 1722 | 1700 | #[test] | |
| 1723 | 1701 | fn suggest_no_segment_scan_when_input_has_dot() { | |
| 1724 | 1702 | let idx = test_index(); | |
| 1725 | - | // "electronic.hou" is a dotted input — tier 2 should NOT run | |
| 1703 | + | // "electronic.hou" is a dotted input, tier 2 should NOT run | |
| 1726 | 1704 | // This means only path-prefix matching, which finds nothing | |
| 1727 | 1705 | // (no tag starts with "electronic.hou") | |
| 1728 | 1706 | assert!(idx.suggest("electronic.hou", 10).is_empty()); | |
| @@ -1759,7 +1737,7 @@ mod tests { | |||
| 1759 | 1737 | #[test] | |
| 1760 | 1738 | fn suggest_segment_only_matches_segment_start() { | |
| 1761 | 1739 | let idx = test_index(); | |
| 1762 | - | // "ock" should NOT match "genre.rock" — we match segment starts, not substrings | |
| 1740 | + | // "ock" should NOT match "genre.rock", we match segment starts, not substrings | |
| 1763 | 1741 | assert!(idx.suggest("ock", 10).is_empty()); | |
| 1764 | 1742 | } | |
| 1765 | 1743 | ||
| @@ -1812,7 +1790,7 @@ mod tests { | |||
| 1812 | 1790 | ||
| 1813 | 1791 | #[test] | |
| 1814 | 1792 | fn edit_distance_transposition_as_two_ops() { | |
| 1815 | - | // "ab" → "ba" is 2 (sub+sub), not 1 (no Damerau) | |
| 1793 | + | // "ab" -> "ba" is 2 (sub+sub), not 1 (no Damerau) | |
| 1816 | 1794 | assert_eq!(edit_distance("ab", "ba", 2), Some(2)); | |
| 1817 | 1795 | } | |
| 1818 | 1796 | ||
| @@ -1839,7 +1817,7 @@ mod tests { | |||
| 1839 | 1817 | #[test] | |
| 1840 | 1818 | fn suggest_fuzzy_typo_in_root_segment() { | |
| 1841 | 1819 | let idx = test_index(); | |
| 1842 | - | // "genr" → "genre" (distance 1) | |
| 1820 | + | // "genr" -> "genre" (distance 1) | |
| 1843 | 1821 | let results = idx.suggest_fuzzy("genr", 10); | |
| 1844 | 1822 | assert!(results.contains(&"genre.electronic.house")); | |
| 1845 | 1823 | assert!(results.contains(&"genre.rock")); | |
| @@ -1848,7 +1826,7 @@ mod tests { | |||
| 1848 | 1826 | #[test] | |
| 1849 | 1827 | fn suggest_fuzzy_typo_in_leaf_segment() { | |
| 1850 | 1828 | let idx = test_index(); | |
| 1851 | - | // "hous" → "house" (distance 1) | |
| 1829 | + | // "hous" -> "house" (distance 1) | |
| 1852 | 1830 | let results = idx.suggest_fuzzy("hous", 10); | |
| 1853 | 1831 | assert!(results.contains(&"genre.electronic.house")); | |
| 1854 | 1832 | } | |
| @@ -1879,7 +1857,7 @@ mod tests { | |||
| 1879 | 1857 | #[test] | |
| 1880 | 1858 | fn suggest_fuzzy_distance_2() { | |
| 1881 | 1859 | let idx = test_index(); | |
| 1882 | - | // "drak" → "dark" (distance 2: transposition = sub+sub) | |
| 1860 | + | // "drak" -> "dark" (distance 2: transposition = sub+sub) | |
| 1883 | 1861 | let results = idx.suggest_fuzzy("drak", 10); | |
| 1884 | 1862 | assert!(results.contains(&"mood.dark")); | |
| 1885 | 1863 | } | |
| @@ -1897,7 +1875,7 @@ mod tests { | |||
| 1897 | 1875 | "mood.dork".into(), | |
| 1898 | 1876 | "mood.dxxx".into(), | |
| 1899 | 1877 | ]); | |
| 1900 | - | // "dark" → segment "dark"=0 (tier 2 hit), "dork"=1, "dxxx"=3 (exceeds threshold) | |
| 1878 | + | // "dark" -> segment "dark"=0 (tier 2 hit), "dork"=1, "dxxx"=3 (exceeds threshold) | |
| 1901 | 1879 | let results = idx.suggest_fuzzy("dark", 10); | |
| 1902 | 1880 | // tier 2 picks up mood.dark (segment "dark" starts_with "dark") | |
| 1903 | 1881 | // tier 3 fuzzy adds mood.dork (distance 1) | |
| @@ -1983,7 +1961,7 @@ mod tests { | |||
| 1983 | 1961 | ||
| 1984 | 1962 | #[test] | |
| 1985 | 1963 | fn merge_tags_carries_descendants() { | |
| 1986 | - | // The subtree, not just the exact tag, must move — descendants of | |
| 1964 | + | // The subtree, not just the exact tag, must move; descendants of | |
| 1987 | 1965 | // `source` were orphaned before the fuzz-1 fix (merge_tags-orphans). | |
| 1988 | 1966 | let mut idx = TagIndex::new(vec![ | |
| 1989 | 1967 | "genre.electronic".into(), | |
| @@ -2038,11 +2016,9 @@ mod tests { | |||
| 2038 | 2016 | assert!(idx.contains("x.y.c")); | |
| 2039 | 2017 | } | |
| 2040 | 2018 | ||
| 2041 | - | // ────────────────────────────────────────────────────────────────────── | |
| 2042 | - | // Mutation-coverage tests — added to close gaps surfaced by cargo-mutants. | |
| 2019 | + | // Mutation-coverage tests, added to close gaps surfaced by cargo-mutants. | |
| 2043 | 2020 | // Each test pins down a specific decision boundary that prior tests did | |
| 2044 | 2021 | // not constrain. See `_private/docs/meta/archive/remediation_todo.md` § C1 for context. | |
| 2045 | - | // ────────────────────────────────────────────────────────────────────── | |
| 2046 | 2022 | ||
| 2047 | 2023 | #[test] | |
| 2048 | 2024 | fn tag_error_display_includes_message() { | |
| @@ -2076,11 +2052,11 @@ mod tests { | |||
| 2076 | 2052 | // the sort order across tags. | |
| 2077 | 2053 | // | |
| 2078 | 2054 | // Setup: | |
| 2079 | - | // tag1 = "abxy.xz" — input "xy" | |
| 2080 | - | // orig: "abxy" dist 2 (continue), "xz" dist 1 → best=1 | |
| 2081 | - | // mut: "abxy" dist 2 → break → best=2 | |
| 2082 | - | // tag2 = "aaaa.bb" — input "xy" | |
| 2083 | - | // both: "aaaa" None, "bb" dist 2 → best=2 | |
| 2055 | + | // tag1 = "abxy.xz", input "xy" | |
| 2056 | + | // orig: "abxy" dist 2 (continue), "xz" dist 1 -> best=1 | |
| 2057 | + | // mut: "abxy" dist 2 -> break -> best=2 | |
| 2058 | + | // tag2 = "aaaa.bb", input "xy" | |
| 2059 | + | // both: "aaaa" None, "bb" dist 2 -> best=2 | |
| 2084 | 2060 | // | |
| 2085 | 2061 | // Original ordering by score: [abxy.xz (1), aaaa.bb (2)] | |
| 2086 | 2062 | // Mutant ordering by score: [aaaa.bb (2), abxy.xz (2)] (alphabetical tiebreak) | |
| @@ -2098,7 +2074,7 @@ mod tests { | |||
| 2098 | 2074 | ||
| 2099 | 2075 | #[test] | |
| 2100 | 2076 | fn suggest_fuzzy_distance_one_via_segment_typo() { | |
| 2101 | - | // Catches L518 edit_distance arithmetic mutation `row[i - 1]` → `row[i / 1]` | |
| 2077 | + | // Catches L518 edit_distance arithmetic mutation `row[i - 1]` -> `row[i / 1]` | |
| 2102 | 2078 | // (which equals `row[i]`, breaking the DP recurrence). | |
| 2103 | 2079 | // | |
| 2104 | 2080 | // With the broken DP, the computed Levenshtein distance changes; with | |
| @@ -2106,7 +2082,7 @@ mod tests { | |||
| 2106 | 2082 | // would either reject the candidate (distance > 2) or accept a wrong | |
| 2107 | 2083 | // candidate that should have been rejected. | |
| 2108 | 2084 | // | |
| 2109 | - | // Test pair: "gerne" → "genre" is a single transposition (distance 2: | |
| 2085 | + | // Test pair: "gerne" -> "genre" is a single transposition (distance 2: | |
| 2110 | 2086 | // delete 'r', insert 'r' at the other position; or two substitutions). | |
| 2111 | 2087 | // "junk" vs every segment is distance ≥ 3, must NOT appear. | |
| 2112 | 2088 | let idx = TagIndex::new(vec!["genre.rock".into(), "junk.bar".into()]); | |
| @@ -2127,7 +2103,7 @@ mod tests { | |||
| 2127 | 2103 | // tag farther than that should appear from fuzzy matching). A broken | |
| 2128 | 2104 | // edit_distance under L518 might erroneously return Some(n) for n > 2. | |
| 2129 | 2105 | let idx = TagIndex::new(vec!["abcdefg".into(), "hijklmn".into()]); | |
| 2130 | - | // "xy" is distance 7 from "abcdefg" and 7 from "hijklmn" — neither | |
| 2106 | + | // "xy" is distance 7 from "abcdefg" and 7 from "hijklmn", neither | |
| 2131 | 2107 | // can match under any correct implementation with threshold 2. | |
| 2132 | 2108 | let results = idx.suggest_fuzzy("xy", 10); | |
| 2133 | 2109 | assert!( | |
| @@ -2138,17 +2114,17 @@ mod tests { | |||
| 2138 | 2114 | ||
| 2139 | 2115 | #[test] | |
| 2140 | 2116 | fn suggest_fuzzy_handles_rotation_distance_two() { | |
| 2141 | - | // Targeted at L518 `row[i - 1]` → `row[i / 1]` (= `row[i]`) mutation. | |
| 2117 | + | // Targeted at L518 `row[i - 1]` -> `row[i / 1]` (= `row[i]`) mutation. | |
| 2142 | 2118 | // | |
| 2143 | 2119 | // The mutation drops the "delete from `a`" axis of the Levenshtein DP. | |
| 2144 | - | // The broken DP is ARGUMENT-ORDER DEPENDENT — `edit_distance("abc", "cab")` | |
| 2120 | + | // The broken DP is ARGUMENT-ORDER DEPENDENT: `edit_distance("abc", "cab")` | |
| 2145 | 2121 | // computes the wrong value while `edit_distance("cab", "abc")` happens | |
| 2146 | 2122 | // to be correct. The function is called as `edit_distance(input, seg, 2)`, | |
| 2147 | 2123 | // so the test must pick (input, segment) such that `input` is the side | |
| 2148 | 2124 | // where the broken DP fails. | |
| 2149 | 2125 | // | |
| 2150 | 2126 | // Empirically (verified by hand-trace + manual mutation): | |
| 2151 | - | // edit_distance("abc", "cab", 2) — correct: Some(2); mutant: None | |
| 2127 | + | // edit_distance("abc", "cab", 2), correct: Some(2); mutant: None | |
| 2152 | 2128 | // | |
| 2153 | 2129 | // So: input = "abc", a tag whose segment is "cab". | |
| 2154 | 2130 | let idx = TagIndex::new(vec!["cab.x".into()]); |
| @@ -35,24 +35,24 @@ pedantic = { level = "warn", priority = -1 } | |||
| 35 | 35 | # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything | |
| 36 | 36 | # else in `pedantic` stays a warning. Keep this block identical across repos. | |
| 37 | 37 | module_name_repetitions = "allow" | |
| 38 | - | # Doc lints — no docs-completeness push underway. | |
| 38 | + | # Doc lints. No docs-completeness push is underway. | |
| 39 | 39 | missing_errors_doc = "allow" | |
| 40 | 40 | missing_panics_doc = "allow" | |
| 41 | 41 | doc_markdown = "allow" | |
| 42 | - | # Numeric casts — endemic and mostly intentional in size/byte math. | |
| 42 | + | # Numeric casts. Endemic and mostly intentional in size and byte math. | |
| 43 | 43 | cast_possible_truncation = "allow" | |
| 44 | 44 | cast_sign_loss = "allow" | |
| 45 | 45 | cast_precision_loss = "allow" | |
| 46 | 46 | cast_possible_wrap = "allow" | |
| 47 | 47 | cast_lossless = "allow" | |
| 48 | - | # Subjective structure/style nags — high churn, low signal. | |
| 48 | + | # Subjective structure and style nags. High churn, low signal. | |
| 49 | 49 | must_use_candidate = "allow" | |
| 50 | 50 | too_many_lines = "allow" | |
| 51 | 51 | struct_excessive_bools = "allow" | |
| 52 | 52 | similar_names = "allow" | |
| 53 | 53 | items_after_statements = "allow" | |
| 54 | 54 | single_match_else = "allow" | |
| 55 | - | # Frequent false-positives in TUI/router-heavy code — added from the buckets breakdown. | |
| 55 | + | # Frequent false-positives in TUI and router-heavy code. | |
| 56 | 56 | match_same_arms = "allow" | |
| 57 | 57 | unnecessary_wraps = "allow" | |
| 58 | 58 | type_complexity = "allow" |
| @@ -32,24 +32,24 @@ pedantic = { level = "warn", priority = -1 } | |||
| 32 | 32 | # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything | |
| 33 | 33 | # else in `pedantic` stays a warning. Keep this block identical across repos. | |
| 34 | 34 | module_name_repetitions = "allow" | |
| 35 | - | # Doc lints — no docs-completeness push underway. | |
| 35 | + | # Doc lints. No docs-completeness push is underway. | |
| 36 | 36 | missing_errors_doc = "allow" | |
| 37 | 37 | missing_panics_doc = "allow" | |
| 38 | 38 | doc_markdown = "allow" | |
| 39 | - | # Numeric casts — endemic and mostly intentional in size/byte math. | |
| 39 | + | # Numeric casts. Endemic and mostly intentional in size and byte math. | |
| 40 | 40 | cast_possible_truncation = "allow" | |
| 41 | 41 | cast_sign_loss = "allow" | |
| 42 | 42 | cast_precision_loss = "allow" | |
| 43 | 43 | cast_possible_wrap = "allow" | |
| 44 | 44 | cast_lossless = "allow" | |
| 45 | - | # Subjective structure/style nags — high churn, low signal. | |
| 45 | + | # Subjective structure and style nags. High churn, low signal. | |
| 46 | 46 | must_use_candidate = "allow" | |
| 47 | 47 | too_many_lines = "allow" | |
| 48 | 48 | struct_excessive_bools = "allow" | |
| 49 | 49 | similar_names = "allow" | |
| 50 | 50 | items_after_statements = "allow" | |
| 51 | 51 | single_match_else = "allow" | |
| 52 | - | # Frequent false-positives in TUI/router-heavy code — added from the buckets breakdown. | |
| 52 | + | # Frequent false-positives in TUI and router-heavy code. | |
| 53 | 53 | match_same_arms = "allow" | |
| 54 | 54 | unnecessary_wraps = "allow" | |
| 55 | 55 | type_complexity = "allow" |