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