fix(layout): Harden edge routing robustness and add channel fallback diagnostics#46
Merged
Merged
Conversation
d2_escape only handled backslash, double-quote, newline, and carriage return. D2 treats angle brackets, braces, and pipe as structural delimiters in node/edge labels, so unescaped occurrences in table or FK names could produce invalid D2 output.
Barycenter and median sort in order.rs, and obstacle distance comparison in obstacle.rs, used partial_cmp with a fallback to Equal. If NaN leaked into coordinates the sort would lose determinism and produce unreproducible layout differences. f64::total_cmp / f32::total_cmp give a consistent total order that treats NaN deterministically.
Integer conversions (usize → u32/u16) in channel candidate generation used expect(), which would panic on extremely large graphs. Replace with unwrap_or(MAX) / saturating_add so overflow degrades gracefully instead of crashing.
Extract route_single_edge (per-edge path computation) and finalize_routed_edge (label placement) from the monolithic 300+ line function. The orchestrator now delegates to these helpers, making each phase independently testable and easier to debug.
When obstacle_aware_channel_for_edge fails to find any viable channel candidate and the router falls back to simple backbone routing, this is now counted in RoutingDiagnostics and surfaced in the layout-json debug output. A dedicated test verifies the diagnostic fires when a large blocker node covers the entire inter-rank channel space.
Code Metrics Report
Details | | main (d0c858e) | #46 (eb2e781) | +/- |
|---------------------|----------------|---------------|-------|
+ | Coverage | 94.1% | 94.1% | +0.0% |
| Files | 73 | 73 | 0 |
| Lines | 29749 | 29862 | +113 |
+ | Covered | 28004 | 28117 | +113 |
- | Test Execution Time | 1m39s | 1m42s | +3s |Code coverage of files in pull request scope (95.4% → 95.5%)
Reported by octocov |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
<,>,{,},|) in label output to prevent malformeddiagram syntax
partial_cmp().unwrap_or(Equal)withtotal_cmp()for robust float comparisons innode ordering and obstacle distance
try_from().expect()with saturating fallbacks to eliminate potential panics inchannel candidate generation
route_edges_with_diagnosticsinto discrete routing and finalization phases formaintainability
Changes
<,>,{,},|ind2_escape()to produce valid D2 syntaxtotal_cmp()for float comparisons in barycenter and median node orderingtotal_cmp()for obstacle distance comparisontry_from().expect()withunwrap_or(u32::MAX)/unwrap_or(u16::MAX)in channelcandidate generation
saturating_addfor bypass candidate order to avoid overflowroute_single_edge()withSingleEdgeRoutingContextandSingleEdgeResultstructsfinalize_routed_edge()for label placement andPositionedEdgeconstructionchannel_fallback_activationsfield toPositionedGraphRoutingDebugandRoutingDiagnostics