1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
/*! Traits for manipulating the nodes and edges of a graph. */ use crate::handle::{Edge, Handle, NodeId}; /// Methods for adding handles and edges to a graph. pub trait AdditiveHandleGraph { /// Add a node with the provided sequence to the graph, letting /// the graph pick the node ID. fn append_handle(&mut self, sequence: &[u8]) -> Handle; /// Add a node with the provided sequence and ID to the graph. fn create_handle<T: Into<NodeId>>( &mut self, sequence: &[u8], node_id: T, ) -> Handle; /// Insert an edge into the graph. Implementations may panic if /// both handles of the edge do not already exist. fn create_edge(&mut self, edge: Edge); } /// Methods for removing handles and edges from a graph. pub trait SubtractiveHandleGraph { /// Remove a handle from the graph, returning `true` if the handle /// existed. /// /// Implementations may destroy or otherwise modify paths that /// cover the handle. fn remove_handle(&mut self, handle: Handle) -> bool; /// Remove an edge from the graph, returning `true` if the edge /// existed. fn remove_edge(&mut self, edge: Edge) -> bool; fn clear_graph(&mut self); } /// Methods for manipulating handles that already exist in a graph. pub trait MutableHandles: AdditiveHandleGraph { /// Divide the given handle at the provided `offsets`, in terms of /// the node's sequence. Creates `offsets.len() - 1` new handles, /// and updates the edges accordingly. /// /// Implementations should update paths that include a step on /// `handle` by inserting the new handles after that step. fn divide_handle( &mut self, handle: Handle, offsets: Vec<usize>, ) -> Vec<Handle>; /// Divide the given handle at the provided offset, creating one /// new handle. Default implementation uses `divide_handle()`, and /// there's probably no need to provide another implementation. /// /// Implementations should update paths that include a step on /// `handle` by inserting the new handles after that step. fn split_handle( &mut self, handle: Handle, offset: usize, ) -> (Handle, Handle) { let handles = self.divide_handle(handle, vec![offset]); (handles[0], handles[1]) } /// Transform the node that `handle` corresponds to so that the /// orientation of `handle` becomes the node's forward /// orientation. I.e. if `handle` is reverse, the node will be /// reversed. Returns the new handle. fn apply_orientation(&mut self, handle: Handle) -> Handle; } /// Applying transformations to all IDs in a graph, and applying sort orders. pub trait TransformNodeIds { /// Reassign all node IDs in the graph using the provided /// `transform` function. `transform` is `Copy + Send + Sync` as /// some implementations may perform part of the work in parallel. fn transform_node_ids<F>(&mut self, transform: F) where F: Fn(NodeId) -> NodeId + Copy + Send + Sync; /// Reassign the node IDs using the provided ordering. `order` /// must have one element for each node in the graph, and the node /// IDs will be used to index the slice. fn apply_ordering(&mut self, order: &[Handle]); } /// A graph that supports all forms of handle- and edge-related /// mutation. /// /// Has a blanket implementation for all graphs that implement the /// other traits in this module. pub trait MutableHandleGraph: AdditiveHandleGraph + SubtractiveHandleGraph + MutableHandles + TransformNodeIds { } impl<T> MutableHandleGraph for T where T: AdditiveHandleGraph + SubtractiveHandleGraph + MutableHandles + TransformNodeIds { }