Skip to content

Commit 314e837

Browse files
committed
Fixed: enforce per-insertion validation for PLManifoldStrict topology
Correct the validation policy during batch construction so that topologies requiring vertex links maintain Always validation. This ensures structural guarantees are preserved during bulk operations. Additionally updates MSRV to 1.94, refreshes dependencies, and expands contributor guidelines in AGENTS.md. Refs: issue-228
1 parent bc965ed commit 314e837

7 files changed

Lines changed: 43 additions & 18 deletions

File tree

AGENTS.md

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,16 @@ When user requests commit message generation:
4545
- Prefer borrowed APIs by default:
4646
take references (`&T`, `&mut T`, `&[T]`) as arguments and return borrowed views (`&T`, `&[T]`) when possible.
4747
Only take ownership or return `Vec`/allocated data when required.
48+
- **Error handling**:
49+
- All public functions must return `Result` types
50+
- Private functions should return `Result` if called from public functions to surface errors properly
51+
- As a scientific library, panics are rarely acceptable - prefer explicit error propagation
52+
- Define error types at the top of the relevant module/file (module-local errors, not centralized)
53+
- **Preludes**: Keep minimal and orthogonal by function. Users should be able to import well-named preludes to accomplish
54+
specific goals without bringing in unrelated items.
4855
- Integration tests in `tests/*.rs` are separate crates; add a crate-level doc comment (`//! ...`) at the top to satisfy clippy `missing_docs` (CI uses `-D warnings`).
4956
- **Module layout**: Never use `mod.rs`.
50-
Declare modules in `src/lib.rs` (and `src/main.rs` for binaries), including nested modules via inline `pub mod foo { pub mod bar; }` when needed.
57+
Declare modules in `src/lib.rs`, including nested modules via inline `pub mod foo { pub mod bar; }` when needed.
5158

5259
### Python
5360

@@ -59,21 +66,27 @@ When user requests commit message generation:
5966
## Common Commands
6067

6168
```bash
62-
just fix # Apply formatters/auto-fixes (mutating)
69+
just fix # Apply formatters/auto-fixes (mutating) - most formatters run automatically
6370
just check # Lint/validators (non-mutating)
6471
just ci # Full CI run (checks + all tests + examples + bench compile)
65-
just ci-slow # CI + slow tests (100+ vertices)
72+
just ci-slow # CI + slow tests (100+ vertices) - long-running
6673
just lint # All linting
6774
just test # Lib and doc tests
6875
just test-integration # Integration tests (includes proptests)
6976
just test-all # All tests (Rust + Python)
7077
just examples # Run all examples
78+
just changelog # Regenerate CHANGELOG.md from git commits
7179
```
7280

81+
## Testing Guidance
82+
83+
- **Property tests**: Integration tests include proptests; failures show seed for reproduction
84+
- **Documentation**: After Rust changes, run `just doc-check` to verify docs build
85+
- **Validation order**: Run formatters (`just fix`) before tests to avoid formatting noise in diffs
86+
7387
### Changelog
7488

75-
- Never edit `CHANGELOG.md` directly - it's auto-generated from git commits
76-
- Use `just changelog` to regenerate
89+
- Never edit `CHANGELOG.md` directly - it's auto-generated from git commits via `just changelog`
7790

7891
### GitHub Issues
7992

@@ -95,7 +108,7 @@ When creating or updating issues:
95108

96109
## Project Context
97110

98-
- **Rust** d-dimensional Delaunay triangulation library (MSRV 1.93.1, Edition 2024)
111+
- **Rust** d-dimensional Delaunay triangulation library (MSRV 1.94, Edition 2024)
99112
- **No unsafe code**: `#![forbid(unsafe_code)]`
100113
- **Architecture**: Generic with `const D: usize` for dimension (tested 2D-5D)
101114
- **Modules**: `src/core/` (data structures), `src/geometry/` (predicates)

Cargo.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "delaunay"
33
version = "0.7.1"
44
edition = "2024"
5-
rust-version = "1.93.1"
5+
rust-version = "1.94"
66
authors = [ "Adam Getchell <adam@adamgetchell.org>" ]
77
homepage = "https://github.com/acgetchell/delaunay"
88
documentation = "https://docs.rs/delaunay"
@@ -19,7 +19,7 @@ readme = "README.md"
1919
allocation-counter = { version = "0.8.1", optional = true } # for memory profiling
2020
arc-swap = "1.8.2"
2121
derive_builder = "0.20.2"
22-
la-stack = "0.1.3"
22+
la-stack = "0.2.0"
2323
tracing = "0.1.44"
2424
rustc-hash = "2.1.1" # Fast non-cryptographic hashing for performance
2525
smallvec = { version = "1.15.1", features = [ "serde" ] } # Stack allocation for small collections
@@ -29,7 +29,7 @@ rand = "0.10.0"
2929
serde = { version = "1.0.228", features = [ "derive" ] }
3030
slotmap = { version = "1.1.1", features = [ "serde" ] }
3131
thiserror = "2.0.18"
32-
uuid = { version = "1.21.0", features = [ "v4", "serde", "fast-rng" ] }
32+
uuid = { version = "1.22.0", features = [ "v4", "serde", "fast-rng" ] }
3333

3434
[dev-dependencies]
3535
approx = "0.5.1"

clippy.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# This ensures consistent configuration across all developers and IDEs
33

44
# Minimum Supported Rust Version - matches Cargo.toml and rust-toolchain.toml
5-
msrv = "1.93.1"
5+
msrv = "1.94"
66

77
# Note: Lint levels are controlled via command-line flags in AGENTS.md:
88
# cargo clippy --workspace --all-targets --all-features -- -D warnings -W clippy::pedantic -W clippy::nursery -W clippy::cargo

examples/memory_analysis.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ macro_rules! generate_memory_analysis {
5656
clippy::too_many_lines,
5757
reason = "Example keeps analysis flow in one function for readability"
5858
)]
59+
#[expect(
60+
clippy::result_large_err,
61+
reason = "ConvexHullConstructionError contains TdsValidationError which is large; performance impact is negligible in this example"
62+
)]
5963
fn $name(point_counts: &[usize], seeds: &[u64]) {
6064
let mut any_success = false;
6165
for &n_points in point_counts {

rust-toolchain.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[toolchain]
22
# Pin to MSRV as specified in Cargo.toml
3-
channel = "1.93.1"
3+
channel = "1.94"
44

55
# Essential components for development
66
components = [

src/core/delaunay_triangulation.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2745,13 +2745,17 @@ where
27452745
// potential issue (e.g. after rollback/retry). A comprehensive post-
27462746
// construction validation in finalize_bulk_construction catches any issues
27472747
// that slip through.
2748+
//
2749+
// Exception: PLManifoldStrict requires per-insertion vertex-link validation,
2750+
// so we must use ValidationPolicy::Always to satisfy that guarantee.
27482751
let original_validation_policy = dt.tri.validation_policy;
27492752
dt.tri.validation_policy = if dt
27502753
.tri
27512754
.topology_guarantee
27522755
.requires_vertex_links_during_insertion()
2753-
|| dt.tri.topology_guarantee.requires_ridge_links()
27542756
{
2757+
ValidationPolicy::Always
2758+
} else if dt.tri.topology_guarantee.requires_ridge_links() {
27552759
ValidationPolicy::OnSuspicion
27562760
} else {
27572761
ValidationPolicy::DebugOnly
@@ -2850,13 +2854,17 @@ where
28502854
// During batch construction, use suspicion-driven validation instead of
28512855
// per-insertion validation (see _with_construction_statistics variant for
28522856
// rationale: O(n²) avoidance + post-construction catch-all).
2857+
//
2858+
// Exception: PLManifoldStrict requires per-insertion vertex-link validation,
2859+
// so we must use ValidationPolicy::Always to satisfy that guarantee.
28532860
let original_validation_policy = dt.tri.validation_policy;
28542861
dt.tri.validation_policy = if dt
28552862
.tri
28562863
.topology_guarantee
28572864
.requires_vertex_links_during_insertion()
2858-
|| dt.tri.topology_guarantee.requires_ridge_links()
28592865
{
2866+
ValidationPolicy::Always
2867+
} else if dt.tri.topology_guarantee.requires_ridge_links() {
28602868
ValidationPolicy::OnSuspicion
28612869
} else {
28622870
ValidationPolicy::DebugOnly

0 commit comments

Comments
 (0)