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
{
}