pub struct Graph<NodeT: NodeEnum> { /* private fields */ }Expand description
A graph with typed nodes The graph can only by modified by commiting a transaction, which avoids mutable borrow of the graph
§Example:
use ttgraph::*;
#[derive(TypedNode)]
struct NodeA{
link: NodeIndex,
data: usize,
}
#[derive(TypedNode)]
struct NodeB{
links: BTreeSet<NodeIndex>,
another_data: String,
}
node_enum!{
enum Node{
A(NodeA),
B(NodeB)
}
}
let ctx = Context::new();
let mut graph = Graph::<Node>::new(&ctx);
let mut trans = Transaction::new(&ctx);
// Does some operations on the transaction
graph.commit(trans);Implementations§
source§impl<NodeT: NodeEnum> Graph<NodeT>
impl<NodeT: NodeEnum> Graph<NodeT>
sourcepub fn get(&self, idx: NodeIndex) -> Option<&NodeT>
pub fn get(&self, idx: NodeIndex) -> Option<&NodeT>
Get the reference of a node. For convinience, if the type of the node is previously known, use get_node!() instead.
§Example
use ttgraph::*;
#[derive(TypedNode)]
struct NodeA{
data: usize,
}
node_enum!{
enum Node{
A(NodeA)
}
}
let ctx = Context::new();
let mut graph = Graph::<Node>::new(&ctx);
let mut trans = Transaction::new(&ctx);
let idx = trans.insert(Node::A(NodeA{
data: 1
}));
graph.commit(trans);
// node: Option<&Node>
let node = graph.get(idx);
if let Some(Node::A(node)) = node {
assert_eq!(node.data, 1);
} else {
panic!();
}
assert!(graph.get(NodeIndex::empty()).is_none());sourcepub fn iter(&self) -> Iter<'_, NodeIndex, NodeT> ⓘ
pub fn iter(&self) -> Iter<'_, NodeIndex, NodeT> ⓘ
Iterate all nodes in the graph following the order of NodeIndex.
If only a type of node is wanted, use iter_nodes! instead.
§Example
use ttgraph::*;
#[derive(TypedNode)]
struct NodeA{
a: usize
}
#[derive(TypedNode)]
struct NodeB{
b: usize
}
node_enum!{
enum Node{
A(NodeA),
B(NodeB),
}
}
let ctx = Context::new();
let mut graph = Graph::<Node>::new(&ctx);
let mut trans = Transaction::new(&ctx);
trans.insert(Node::A(NodeA{ a: 1 }));
trans.insert(Node::A(NodeA{ a: 2 }));
trans.insert(Node::B(NodeB{ b: 0 }));
graph.commit(trans);
// iterator.next() returns Option<(NodeIndex, &Node)>
let iterator = graph.iter();
for (i, (_, node)) in (1..3).zip(iterator) {
if let Node::A(a) = node {
assert_eq!(i, a.a);
} else {
panic!();
}
}sourcepub fn iter_group(
&self,
name: &'static str,
) -> impl Iterator<Item = (NodeIndex, &NodeT)>
pub fn iter_group( &self, name: &'static str, ) -> impl Iterator<Item = (NodeIndex, &NodeT)>
Iterate all nodes within the named group
§Example
use ttgraph::*;
#[derive(TypedNode, Debug)]
struct NodeA {
a: usize,
}
#[derive(TypedNode, Debug)]
struct NodeB {
b: usize,
}
#[derive(TypedNode, Debug)]
struct NodeC {
c: usize,
}
#[derive(TypedNode, Debug)]
struct NodeD {
d: usize,
}
node_enum! {
#[derive(Debug)]
enum MultiNodes{
A(NodeA),
B(NodeB),
C(NodeC),
D(NodeD),
}
group!{
first{A, B},
second{C, D},
third{A, D},
one{B},
all{A, B, C, D},
}
}
let ctx = Context::new();
let mut graph = Graph::<MultiNodes>::new(&ctx);
let mut trans = Transaction::new(&ctx);
let a = trans.insert(MultiNodes::A(NodeA { a: 1 }));
let b = trans.insert(MultiNodes::B(NodeB { b: 2 }));
let c = trans.insert(MultiNodes::C(NodeC { c: 3 }));
let d = trans.insert(MultiNodes::D(NodeD { d: 4 }));
graph.commit(trans);
assert_eq!(Vec::from_iter(graph.iter_group("first").map(|(x, _)| x)), vec![a, b]);
assert_eq!(Vec::from_iter(graph.iter_group("second").map(|(x, _)| x)), vec![c, d]);
assert_eq!(Vec::from_iter(graph.iter_group("third").map(|(x, _)| x)), vec![a, d]);
assert_eq!(Vec::from_iter(graph.iter_group("one").map(|(x, _)| x)), vec![b]);
assert_eq!(Vec::from_iter(graph.iter_group("all").map(|(x, _)| x)), vec![a, b, c, d]);sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Get the number of nodes in a graph
§Example
use ttgraph::*;
#[derive(TypedNode)]
struct NodeA{
data: usize,
}
node_enum!{
enum Node{
A(NodeA)
}
}
let ctx = Context::new();
let mut graph = Graph::<Node>::new(&ctx);
assert_eq!(graph.len(), 0);
let mut trans = Transaction::new(&ctx);
trans.insert(Node::A(NodeA{data: 1}));
trans.insert(Node::A(NodeA{data: 1}));
trans.insert(Node::A(NodeA{data: 1}));
graph.commit(trans);
assert_eq!(graph.len(), 3);sourcepub fn commit(&mut self, t: Transaction<'_, NodeT>)
pub fn commit(&mut self, t: Transaction<'_, NodeT>)
Commit an Transaction to modify the graph
Operation order:
- Redirect nodes
- Insert new nodes
- Modify nodes
- Update nodes
- Redirect all nodes
- Remove nodes
- Add/Remove links due to bidirectional declaration
- Check link types
§Panics
Panic if the transaction and the graph have different context
§Example
use ttgraph::*;
#[derive(TypedNode)]
struct NodeA{
data: usize,
}
node_enum!{
enum Node{
A(NodeA)
}
}
let ctx = Context::new();
let mut graph = Graph::<Node>::new(&ctx);
let mut trans = Transaction::new(&ctx);
trans.insert(Node::A(NodeA{data: 1}));
graph.commit(trans);sourcepub fn commit_checked(
&mut self,
t: Transaction<'_, NodeT>,
checks: &GraphCheck<NodeT>,
)
pub fn commit_checked( &mut self, t: Transaction<'_, NodeT>, checks: &GraphCheck<NodeT>, )
Similar to commit(), but with additional checks on the changed nodes and links.
See GraphCheck for more information.
sourcepub fn switch_context(self, new_ctx: &Context) -> Self
pub fn switch_context(self, new_ctx: &Context) -> Self
Switch the context and relabel the node ids.
§Usecase:
- Useful when there are a lot of removed
NodeIndex, and after context switching the indexes will be more concise. - Merge two graphs with different context. See
mergefor example.
§Warning:
- Please ensure there is no uncommitted transactions!
NodeIndexpointing to this graph is useless after context switching!
sourcepub fn check_integrity(&self)
pub fn check_integrity(&self)
Check if all links are internal, just for debug
Trait Implementations§
source§impl<NodeT> From<Graph<NodeT>> for GraphSerializer<NodeT>where
NodeT: NodeEnum,
impl<NodeT> From<Graph<NodeT>> for GraphSerializer<NodeT>where
NodeT: NodeEnum,
source§fn from(value: Graph<NodeT>) -> GraphSerializer<NodeT>
fn from(value: Graph<NodeT>) -> GraphSerializer<NodeT>
source§impl<'a, T: NodeEnum + 'a> IntoIterator for &'a Graph<T>
impl<'a, T: NodeEnum + 'a> IntoIterator for &'a Graph<T>
source§impl<T: NodeEnum> IntoIterator for Graph<T>
impl<T: NodeEnum> IntoIterator for Graph<T>
Auto Trait Implementations§
impl<NodeT> Freeze for Graph<NodeT>
impl<NodeT> RefUnwindSafe for Graph<NodeT>
impl<NodeT> Send for Graph<NodeT>
impl<NodeT> Sync for Graph<NodeT>
impl<NodeT> Unpin for Graph<NodeT>
impl<NodeT> UnwindSafe for Graph<NodeT>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit)