#![allow(dead_code)] use std::vec::Vec; use borrow::PartialBorrow; use borrow::partial_borrow as p; use borrow::traits::*; // ============ // === Data === // ============ type NodeId = usize; type EdgeId = usize; #[derive(Debug)] struct Node { outputs: Vec, inputs: Vec, } #[derive(Debug)] struct Edge { from: Option, to: Option, } #[derive(Debug, PartialBorrow)] #[module(crate)] struct Graph { nodes: Vec, edges: Vec, } // ============= // === Utils === // ============= // Requires mutable access to the `graph.edges` field. fn detach_node(graph: p!(& Graph), node: &mut Node) { for edge_id in std::mem::take(&mut node.outputs) { graph.edges[edge_id].from = None; } for edge_id in std::mem::take(&mut node.inputs) { graph.edges[edge_id].to = None; } } // Requires mutable access to all `graph` fields. fn detach_all_nodes(graph: p!(& Graph)) { // Extract the `nodes` field. // The `graph2` variable has a type of `p!(& Graph)`. let (nodes, graph2) = graph.extract_nodes(); for node in nodes { detach_node(graph2.partial_borrow(), node); } } // ============= // === Tests === // ============= #[test] fn test() { // 0 -> 1 -> 2 -> 0 let mut graph = Graph { nodes: vec![ Node { outputs: vec![0], inputs: vec![2] }, // Node 0 Node { outputs: vec![1], inputs: vec![0] }, // Node 1 Node { outputs: vec![2], inputs: vec![1] }, // Node 2 ], edges: vec![ Edge { from: Some(0), to: Some(1) }, // Edge 0 Edge { from: Some(1), to: Some(2) }, // Edge 1 Edge { from: Some(2), to: Some(0) }, // Edge 2 ], }; detach_all_nodes(&mut graph.as_refs_mut().partial_borrow()); for node in &graph.nodes { assert!(node.outputs.is_empty()); assert!(node.inputs.is_empty()); } for edge in &graph.edges { assert!(edge.from.is_none()); assert!(edge.to.is_none()); } }