wolf-graph 0.1.0

Data structures and algorithms for working with graphs with reference or value semantics.
Documentation
mod common;
use common::*;

use anyhow::Result;

use wolf_graph::prelude::*;

#[test]
fn test_creation_1() -> Result<()> {
    let mut c = BlankCompound::new();
    c.add_node(nid!("A"), None::<NodeID>, eid!("rA"))?;
    c.add_node(nid!("B"), None::<NodeID>, eid!("rB"))?;
    assert_eq!(c, c);
    recode(&c, r#"[[["A","B"],[]],["root",[["A","B","root"],[["rA","root","A"],["rB","root","B"]]]]]"#)?;
    Ok(())
}

#[test]
fn test_creation_2() -> Result<()> {
    let mut c = Compound::<Graph::<String, (), ()>>::new()
        .setting_data("Hello".to_string());
    c.add_node(nid!("A"), None::<NodeID>, eid!("rA"))?;
    c.add_node(nid!("B"), None::<NodeID>, eid!("rB"))?;
    c.add_edge(eid!("AB"), nid!("A"), nid!("B"))?;
    assert_eq!(c, c);
    recode(&c, r#"[[["A","B"],[["AB","A","B"]],"Hello"],["root",[["A","B","root"],[["rA","root","A"],["rB","root","B"]]]]]"#)?;
    Ok(())
}

#[test]
fn test_creation_3() -> Result<()> {
    let mut c = Compound::<Graph::<String, i32, ()>>::new()
        .setting_data("Hello".to_string());
    c.add_node_with_data(nid!("A"), None::<NodeID>, eid!("rA"), 1)?;
    c.add_node(nid!("B"), None::<NodeID>, eid!("rB"))?;
    c.add_edge(eid!("AB"), nid!("A"), nid!("B"))?;
    assert_eq!(c, c);
    recode(&c, r#"[[[["A",1],["B",0]],[["AB","A","B"]],"Hello"],["root",[["A","B","root"],[["rA","root","A"],["rB","root","B"]]]]]"#)?;
    Ok(())
}

#[test]
fn test_creation_4() -> Result<()> {
    let mut c = Compound::<Graph::<String, i32, Data>>::new()
        .setting_data("Hello".to_string());
    c.add_node_with_data(nid!("A"), None::<NodeID>, eid!("rA"), 1)?;
    c.add_node(nid!("B"), None::<NodeID>, eid!("rB"))?;
    c.add_edge_with_data(eid!("AB"), nid!("A"), nid!("B"), Data::from([1, 2, 3, 4]))?;
    assert_eq!(c, c);
    recode(&c, r#"[[[["A",1],["B",0]],[["AB","A","B","AQIDBA=="]],"Hello"],["root",[["A","B","root"],[["rA","root","A"],["rB","root","B"]]]]]"#)?;
    Ok(())
}

#[test]
fn test_mutators() -> Result<()> {
    // Start with an empty compound graph
    let mut c = BlankCompound::new();
    recode(&c, r#"[[[],[]],["root",[["root"],[]]]]"#)?;

    // Add a couple nodes
    c.add_node(nid!("A"), None::<NodeID>, eid!("rA"))?;
    c.add_node(nid!("B"), None::<NodeID>, eid!("rB"))?;
    recode(&c, r#"[[["A","B"],[]],["root",[["A","B","root"],[["rA","root","A"],["rB","root","B"]]]]]"#)?;

    // Connect A --> B
    c.add_edge(eid!("AB"), nid!("A"), nid!("B"))?;
    recode(&c, r#"[[["A","B"],[["AB","A","B"]]],["root",[["A","B","root"],[["rA","root","A"],["rB","root","B"]]]]]"#)?;

    // Add C and Connect A --> C
    c.add_node(nid!("C"), None::<NodeID>, eid!("rC"))?;
    c.add_edge(eid!("AC"), nid!("A"), nid!("C"))?;
    recode(&c, r#"[[["A","B","C"],[["AB","A","B"],["AC","A","C"]]],["root",[["A","B","C","root"],[["rA","root","A"],["rB","root","B"],["rC","root","C"]]]]]"#)?;

    // Create Group 1
    c.add_node(nid!("G1"), None::<NodeID>, eid!("r1"))?;
    // Move B into Group 1
    c.move_node(nid!("B"), Some(nid!("G1")))?;
    recode(&c, r#"[[["A","B","C","G1"],[["AB","A","B"],["AC","A","C"]]],["root",[["A","B","C","G1","root"],[["r1","root","G1"],["rA","root","A"],["rB","G1","B"],["rC","root","C"]]]]]"#)?;

    Ok(())
}

#[test]
fn test_builders() -> Result<()> {
    // Start with an empty compound graph
    let c1 = BlankCompound::new();
    recode(&c1, r#"[[[],[]],["root",[["root"],[]]]]"#)?;

    // Add a couple nodes
    let c2 = c1
        .adding_node(nid!("A"), None::<NodeID>, eid!("rA"))?
        .adding_node(nid!("B"), None::<NodeID>, eid!("rB"))?;
    recode(&c2, r#"[[["A","B"],[]],["root",[["A","B","root"],[["rA","root","A"],["rB","root","B"]]]]]"#)?;

    // Connect A --> B
    let c3 = c2
        .adding_edge(eid!("AB"), nid!("A"), nid!("B"))?;
    recode(&c3, r#"[[["A","B"],[["AB","A","B"]]],["root",[["A","B","root"],[["rA","root","A"],["rB","root","B"]]]]]"#)?;

    // Add C and Connect A --> C
    let c4 = c3
        .adding_node(nid!("C"), None::<NodeID>, eid!("rC"))?
        .adding_edge(eid!("AC"), nid!("A"), nid!("C"))?;
    recode(&c4, r#"[[["A","B","C"],[["AB","A","B"],["AC","A","C"]]],["root",[["A","B","C","root"],[["rA","root","A"],["rB","root","B"],["rC","root","C"]]]]]"#)?;

    // Create Group 1
    let c5 = c4
        .adding_node(nid!("G1"), None::<NodeID>, eid!("r1"))?
        .moving_node(nid!("B"), Some(nid!("G1")))?; // Move B into Group 1
    recode(&c5, r#"[[["A","B","C","G1"],[["AB","A","B"],["AC","A","C"]]],["root",[["A","B","C","G1","root"],[["r1","root","G1"],["rA","root","A"],["rB","G1","B"],["rC","root","C"]]]]]"#)?;

    Ok(())
}

#[test]
fn test_with_data() -> Result<()> {
    let mut c = Compound::<DAG<Graph<TestElemData, TestElemData, TestElemData>>>::new()
        .setting_data(TestElemData(1, "Hello".to_string()));
    recode(&c, r#"[[[],[],[1,"Hello"]],["root",[["root"],[]]]]"#)?;
    c.with_data(&|data| {
        data.0 = 10;
        data.1 = "dog".to_string();
    });
    recode(&c, r#"[[[],[],[10,"dog"]],["root",[["root"],[]]]]"#)?;
    assert_eq!(*c.data(), TestElemData(10, "dog".to_string()));
    c.with_data(&|data| {
        data.0 = 20;
        data.1 = "cat".to_string();
    });
    recode(&c, r#"[[[],[],[20,"cat"]],["root",[["root"],[]]]]"#)?;

    c.add_node_with_data(nid!("A"), None::<NodeID>, eid!("rA"), TestElemData(1, "a".to_string()))?;
    c.add_node(nid!("B"), None::<NodeID>, eid!("rB"))?;
    c.add_node(nid!("C"), None::<NodeID>, eid!("rC"))?;
    c.add_edge_with_data(eid!("AB"), nid!("A"), nid!("B"), TestElemData(3, "c".to_string()))?;
    c.add_edge(eid!("AC"), nid!("A"), nid!("C"))?;
    recode(&c, r#"[[[["A",[1,"a"]],["B",[0,""]],["C",[0,""]]],[["AB","A","B",[3,"c"]],["AC","A","C",[0,""]]],[20,"cat"]],["root",[["A","B","C","root"],[["rA","root","A"],["rB","root","B"],["rC","root","C"]]]]]"#)?;
    c.with_node_data(nid!("A"), &|data| {
        data.0 = 30;
        data.1 = "ape".to_string();
    })?;
    assert_eq!(c.node_data(nid!("A"))?.as_ref(), &TestElemData(30, "ape".to_string()));
    c.with_edge_data(eid!("AB"), &|data| {
        data.0 = 40;
        data.1 = "bat".to_string();
    })?;
    assert_eq!(c.edge_data(eid!("AB"))?.as_ref(), &TestElemData(40, "bat".to_string()));
    recode(&c, r#"[[[["A",[30,"ape"]],["B",[0,""]],["C",[0,""]]],[["AB","A","B",[40,"bat"]],["AC","A","C",[0,""]]],[20,"cat"]],["root",[["A","B","C","root"],[["rA","root","A"],["rB","root","B"],["rC","root","C"]]]]]"#)?;

    Ok(())
}