dsalgo 0.3.7

A package for Datastructures and Algorithms.
Documentation
#![allow(dead_code)]

use std::{cell::RefCell, rc::Rc};

pub(crate) struct EdgeData;
pub(crate) struct NodeData;

pub(crate) trait Edge<T = Option<EdgeData>, U = Option<NodeData>> {}

impl<T, U> std::fmt::Debug for dyn Edge<T, U> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Edge")
    }
}

pub(crate) struct Node<T, U> {
    pub(crate) edges: Vec<Rc<RefCell<dyn Edge<U, T>>>>,
    pub(crate) data: T,
}

impl<T: std::fmt::Debug, U> std::fmt::Debug for Node<T, U> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "Node {{ data: {:?}, edegs: {:?}}}",
            self.data, self.edges
        )
    }
}

impl<T: Default, U> Default for Node<T, U> {
    fn default() -> Self {
        Self {
            edges: Vec::new(),
            data: T::default(),
        }
    }
}

#[derive(Debug)]
pub(crate) struct DirectedEdge<T, U> {
    pub(crate) from: Rc<RefCell<Node<U, T>>>,
    pub(crate) to: Rc<RefCell<Node<U, T>>>,
    pub(crate) data: T,
}

impl<T, U> Edge<T, U> for DirectedEdge<T, U> {}

impl<T: Default, U>
    From<(
        Rc<RefCell<Node<U, T>>>,
        Rc<RefCell<Node<U, T>>>,
    )> for DirectedEdge<T, U>
{
    fn from(
        nodes: (
            Rc<RefCell<Node<U, T>>>,
            Rc<RefCell<Node<U, T>>>,
        ),
    ) -> Self {
        Self {
            from: nodes.0,
            to: nodes.1,
            data: T::default(),
        }
    }
}

impl<T, U> DirectedEdge<T, U> {
    pub(crate) fn new(
        from: Rc<RefCell<Node<U, T>>>,
        to: Rc<RefCell<Node<U, T>>>,
        data: T,
    ) -> Self {
        Self { from, to, data }
    }
}

#[derive(Debug)]
pub(crate) struct UndirectedEdge<T, U> {
    pub(crate) left: Rc<RefCell<Node<U, T>>>,
    pub(crate) right: Rc<RefCell<Node<U, T>>>,
    pub(crate) data: T,
}

impl<T, U> Edge<T, U> for UndirectedEdge<T, U> {}

impl<T: Default, U>
    From<(
        Rc<RefCell<Node<U, T>>>,
        Rc<RefCell<Node<U, T>>>,
    )> for UndirectedEdge<T, U>
{
    fn from(
        nodes: (
            Rc<RefCell<Node<U, T>>>,
            Rc<RefCell<Node<U, T>>>,
        ),
    ) -> Self {
        Self {
            left: nodes.0,
            right: nodes.1,
            data: T::default(),
        }
    }
}

impl<T: Clone, U> From<&DirectedEdge<T, U>> for UndirectedEdge<T, U> {
    fn from(edge: &DirectedEdge<T, U>) -> Self {
        Self {
            left: edge.from.clone(),
            right: edge.to.clone(),
            data: edge.data.clone(),
        }
    }
}

impl<T, U> UndirectedEdge<T, U> {
    pub(crate) fn new(
        left: Rc<RefCell<Node<U, T>>>,
        right: Rc<RefCell<Node<U, T>>>,
        data: T,
    ) -> Self {
        Self { left, right, data }
    }
}

#[derive(Debug)]
pub struct MixedGraph<T, U> {
    pub(crate) nodes: Vec<Rc<RefCell<Node<T, U>>>>,
}

impl<T, U> MixedGraph<T, U> {
    pub fn size(&self) -> usize { self.nodes.len() }

    pub fn new(size: usize) -> Self
    where
        T: Default,
    {
        Self {
            nodes: (0..size)
                .map(|_| Rc::new(RefCell::new(Node::default())))
                .collect(),
        }
    }

    pub fn add_node(&mut self)
    where
        T: Default,
    {
        self.nodes.push(Rc::new(RefCell::new(
            Node::default(),
        )));
    }

    pub fn add_directed_edge(&mut self, from: usize, to: usize, data: U)
    where
        T: 'static,
        U: 'static,
    {
        assert!(from < self.size() && to < self.size());
        self.nodes[from].borrow_mut().edges.push(Rc::new(RefCell::new(
            DirectedEdge::new(
                self.nodes[from].clone(),
                self.nodes[to].clone(),
                data,
            ),
        )));
    }

    pub fn add_undirected_edge(&mut self, left: usize, right: usize, data: U)
    where
        T: 'static,
        U: 'static,
    {
        assert!(left < self.size() && right < self.size());
        let edge = Rc::new(RefCell::new(
            UndirectedEdge::new(
                self.nodes[left].clone(),
                self.nodes[right].clone(),
                data,
            ),
        ));
        self.nodes[left].borrow_mut().edges.push(edge.clone());
        self.nodes[right].borrow_mut().edges.push(edge.clone());
    }
}

#[cfg(test)]
mod tests {

    #[test]
    fn test() {
        use std::{cell::RefCell, rc::Rc};

        #[derive(Debug, Default, Clone)]
        struct PureNone;

        let node_left = Rc::new(RefCell::new(
            super::Node::default(),
        ));
        let node_right = Rc::new(RefCell::new(
            super::Node::default(),
        ));
        let edge = Rc::new(RefCell::new(
            super::DirectedEdge::<PureNone, usize>::new(
                node_left.clone(),
                node_right.clone(),
                PureNone,
            ),
        ));
        println!("{:?}", edge);
        println!("{:?}", node_left);
        node_left.borrow_mut().edges.push(edge.clone());
        println!("{:?}", edge);
        println!("{:?}", node_left);
        let edge = Rc::new(RefCell::new(
            super::DirectedEdge::<PureNone, usize>::from((
                node_left.clone(),
                node_right.clone(),
            )),
        ));
        println!("{:?}", edge);
        println!("{:?}", node_left);

        let mut graph = super::MixedGraph::<PureNone, usize>::new(2);
        println!("{:?}", graph);
        graph.add_directed_edge(0, 1, 3);
        println!("{:?}", graph);
        graph.add_undirected_edge(0, 1, 2);
        println!("{:?}", graph);
    }
}