use crate::handle::{Direction, Edge, Handle, NodeId};
use rayon::prelude::*;
pub mod iter;
pub use self::iter::*;
pub trait HandleGraph {
fn min_node_id(&self) -> NodeId;
fn max_node_id(&self) -> NodeId;
fn node_count(&self) -> usize;
fn edge_count(&self) -> usize;
fn total_length(&self) -> usize;
}
pub trait HandleGraphRef:
IntoEdges + IntoHandles + IntoNeighbors + IntoSequences + Copy
{
}
impl<'a, T> HandleGraphRef for &'a T where
&'a T: IntoEdges + IntoHandles + IntoNeighbors + IntoSequences + Copy
{
}
impl<'a, T> HandleGraphRef for &'a mut T where
&'a mut T: IntoEdges + IntoHandles + IntoNeighbors + IntoSequences + Copy
{
}
pub trait IntoHandles: Sized {
type Handles: Iterator<Item = Handle>;
fn handles(self) -> Self::Handles;
#[inline]
fn has_node<I: Into<NodeId>>(self, node_id: I) -> bool {
let node_id = node_id.into();
self.handles().any(|h| h.id() == node_id)
}
}
pub trait IntoHandlesPar {
type HandlesPar: ParallelIterator<Item = Handle>;
fn handles_par(self) -> Self::HandlesPar;
}
pub trait IntoEdges: Sized {
type Edges: Iterator<Item = Edge>;
fn edges(self) -> Self::Edges;
}
pub trait IntoNeighbors: Sized {
type Neighbors: Iterator<Item = Handle>;
fn neighbors(self, handle: Handle, dir: Direction) -> Self::Neighbors;
#[inline]
fn degree(self, handle: Handle, dir: Direction) -> usize {
self.neighbors(handle, dir).count()
}
#[inline]
fn has_edge(self, left: Handle, right: Handle) -> bool {
self.neighbors(left, Direction::Right).any(|h| h == right)
}
}
pub trait IntoSequences: Sized {
type Sequence: Iterator<Item = u8>;
fn sequence(self, handle: Handle) -> Self::Sequence;
#[inline]
fn sequence_vec(self, handle: Handle) -> Vec<u8> {
self.sequence(handle).collect()
}
#[inline]
fn subsequence(self, handle: Handle, start: usize, len: usize) -> Vec<u8> {
self.sequence(handle).skip(start).take(len).collect()
}
#[inline]
fn base(self, handle: Handle, index: usize) -> Option<u8> {
self.sequence(handle).nth(index)
}
#[inline]
fn node_len(self, handle: Handle) -> usize {
self.sequence(handle).count()
}
}