graph-rs 0.2.0

Simple graph library.
Documentation
use self::super::DirectedWeightedGraph;
use std::slice::{Iter, IterMut};

impl<'g, N, W> DirectedWeightedGraph<'g, N, W> for Vec<(N, N, W)>
where
    N: Eq + 'g,
    W: 'g,
{
    type AllWeightedEdges = AllWeightedEdges<'g, N, W>;
    type AllWeightedEdgesMut = AllWeightedEdgesMut<'g, N, W>;

    fn all_edges(&'g self) -> Self::AllWeightedEdges {
        AllWeightedEdges { iter: self.iter() }
    }

    fn all_edges_mut(&'g mut self) -> Self::AllWeightedEdgesMut {
        AllWeightedEdgesMut {
            iter: self.iter_mut(),
        }
    }

    /// Adds an edge to the graph.
    ///
    /// # Complexity
    /// This implementation runs in O(|E|) time. Running in linear time would risk this graph of
    /// becoming a multigraph, where there can be multiple edges between the same nodes.
    fn add_edge(&'g mut self, source: N, sink: N, weight: W) -> Option<(N, N, W)> {
        if let Some(old_weight) = self.edge_weight_mut(&source, &sink) {
            return Some((source, sink, ::std::mem::replace(old_weight, weight)));
        }

        self.push((source, sink, weight));
        None
    }

    fn remove_edge(&'g mut self, source: &N, sink: &N) -> Option<(N, N, W)> {
        for index in 0..self.len() {
            {
                let &(ref current_source, ref current_sink, _) = &self[index];
                if current_source != source || current_sink != sink {
                    continue;
                }
            }
            return Some(self.remove(index));
        }

        None
    }
}

#[derive(Debug, Clone)]
pub struct AllWeightedEdges<'g, N, W>
where
    N: 'g,
    W: 'g,
{
    iter: Iter<'g, (N, N, W)>,
}

impl<'g, N, W> Iterator for AllWeightedEdges<'g, N, W> {
    type Item = (&'g N, &'g N, &'g W);

    fn next(&mut self) -> Option<Self::Item> {
        self.iter
            .next()
            .map(|&(ref source, ref sink, ref weight)| (source, sink, weight))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'g, N, W> ExactSizeIterator for AllWeightedEdges<'g, N, W> {
    fn len(&self) -> usize {
        self.iter.len()
    }
}

#[derive(Debug)]
pub struct AllWeightedEdgesMut<'g, N, W>
where
    N: 'g,
    W: 'g,
{
    iter: IterMut<'g, (N, N, W)>,
}

impl<'g, N, W> Iterator for AllWeightedEdgesMut<'g, N, W> {
    type Item = (&'g N, &'g N, &'g mut W);

    fn next(&mut self) -> Option<Self::Item> {
        self.iter
            .next()
            .map(|&mut (ref source, ref sink, ref mut weight)| {
                (source, sink, weight)
            })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

#[cfg(test)]
mod tests {
    use DirectedWeightedGraph;

    #[test]
    fn test_add_edge() {
        let mut graph = Vec::new();

        graph.add_edge(0, 1, 1.0);
        graph.add_edge(1, 1, 2.0);
        graph.add_edge(1, 2, 3.0);

        assert!(graph.has_edge(&0, &1));
        assert!(graph.has_edge(&1, &1));
        assert!(graph.has_edge(&1, &2));
        assert!(!graph.has_edge(&0, &0));
        assert!(!graph.has_edge(&0, &2));
        assert!(!graph.has_edge(&1, &0));
        assert!(!graph.has_edge(&1, &4));

        assert_eq!(graph.edge_weight(&0, &1), Some(&1.0));
        assert_eq!(graph.edge_weight(&1, &1), Some(&2.0));
        assert_eq!(graph.edge_weight(&1, &2), Some(&3.0));

        assert_eq!(graph.all_edges().len(), 3);
    }
}