///|
pub(all) struct TopologyConflictDetail {
conflict_type : String
route_a : @interlocking.RouteId
route_b : @interlocking.RouteId
conflicting_element : String
} derive(Debug)
///|
pub fn detect_topological_conflicts(
rule_a : @interlocking.InterlockingRule,
rule_b : @interlocking.InterlockingRule,
) -> TopologyConflictDetail? {
if rule_a.id.id == rule_b.id.id {
return None
}
// 1. Check track segment overlap
for tr_a in rule_a.track_sections {
for tr_b in rule_b.track_sections {
if tr_a.id == tr_b.id {
return Some({
conflict_type: "TRACK_OVERLAP",
route_a: rule_a.id,
route_b: rule_b.id,
conflicting_element: "Track Segment #" + tr_a.id.to_string(),
})
}
}
}
// 2. Check turnout position conflicts
for sw_a in rule_a.switches {
for sw_b in rule_b.switches {
if sw_a.turnout_id.id == sw_b.turnout_id.id {
if sw_a.required_position != sw_b.required_position {
return Some({
conflict_type: "TURNOUT_POSITION_CONFLICT",
route_a: rule_a.id,
route_b: rule_b.id,
conflicting_element: "Turnout #" +
sw_a.turnout_id.id.to_string() +
" required " +
sw_a.required_position.to_string() +
" vs " +
sw_b.required_position.to_string(),
})
}
}
}
}
// 3. Check flank protection switch conflicts
for flank_a in rule_a.flank_switches {
for sw_b in rule_b.switches {
if flank_a.turnout_id.id == sw_b.turnout_id.id {
if flank_a.required_position != sw_b.required_position {
return Some({
conflict_type: "FLANK_PROTECTION_CONFLICT",
route_a: rule_a.id,
route_b: rule_b.id,
conflicting_element: "Flank Protection Turnout #" +
flank_a.turnout_id.id.to_string() +
" required " +
flank_a.required_position.to_string(),
})
}
}
}
}
None
}