pub struct Sodg { /* private fields */ }
Expand description
A struct that represents a Surging Object DiGraph (SODG).
You add vertices to it, bind them one to one with edges, put data into some of them, and read data back, for example:
use sodg::Sodg;
use sodg::DeadRelay;
let mut sodg = Sodg::empty();
sodg.add(0).unwrap();
sodg.add(1).unwrap();
sodg.bind(0, 1, "a").unwrap();
sodg.add(2).unwrap();
sodg.bind(1, 2, "b").unwrap();
assert_eq!(2, sodg.find(0, "a.b", &mut DeadRelay::default()).unwrap());
This package is used in reo project, as a memory model for objects and dependencies between them.
Implementations§
source§impl Sodg
impl Sodg
sourcepub fn alert_on(&mut self, a: Alert)
pub fn alert_on(&mut self, a: Alert)
Attach a new alert to this graph.
For example, you don’t want more than one edge to depart from any vertex:
use sodg::Sodg;
let mut g = Sodg::empty();
g.alerts_on().unwrap();
g.alert_on(|g, vx| {
for v in vx {
if g.kids(v).unwrap().len() > 1 {
return vec![format!("Too many kids at ν{v}")];
}
}
return vec![];
});
g.add(0).unwrap();
g.add(1).unwrap();
g.add(2).unwrap();
g.bind(0, 1, "first").unwrap();
assert!(g.bind(0, 2, "second").is_err());
sourcepub fn alerts_off(&mut self)
pub fn alerts_off(&mut self)
Disable all alerts.
source§impl Sodg
impl Sodg
sourcepub fn to_dot(&self) -> String
pub fn to_dot(&self) -> String
Print SODG as a DOT graph.
For example, for this code:
use sodg::Hex;
use sodg::Sodg;
let mut g = Sodg::empty();
g.add(0).unwrap();
g.put(0, Hex::from_str_bytes("hello")).unwrap();
g.add(1).unwrap();
g.bind(0, 1, "foo").unwrap();
g.bind(0, 1, "bar").unwrap();
let dot = g.to_dot();
println!("{}", dot);
The printout will look approximately like this:
digraph {
v0[shape=circle,label="ν0"];
v0 -> v1 [label="bar"];
v0 -> v1 [label="foo"];
v1[shape=circle,label="ν1"];
}
source§impl Sodg
impl Sodg
sourcepub fn find<T: Relay>(&self, v1: u32, loc: &str, relay: &T) -> Result<u32>
pub fn find<T: Relay>(&self, v1: u32, loc: &str, relay: &T) -> Result<u32>
Find a vertex in the Sodg by its locator using a Relay
to provide alternative edge names, if the desired ones are not found.
For example, here is how LambdaRelay
may be used with a
“relaying” function:
use sodg::Sodg;
use sodg::DeadRelay;
use sodg::LambdaRelay;
let mut g = Sodg::empty();
g.add(0).unwrap();
g.add(1).unwrap();
g.bind(0, 1, "foo").unwrap();
assert!(g.find(0, "bar", &DeadRelay::default()).is_err());
let v = g.find(0, "bar", &LambdaRelay::new(|v, a| {
assert_eq!(a, "bar");
Ok("foo".to_string())
})).unwrap();
assert_eq!(1, v);
If v1
is absent, an Err
will be returned.
If searching algorithm fails to find the destination,
an Err
will be returned.
source§impl Sodg
impl Sodg
sourcepub fn merge(&mut self, g: &Sodg, left: u32, right: u32) -> Result<()>
pub fn merge(&mut self, g: &Sodg, left: u32, right: u32) -> Result<()>
Merge another graph into the current one.
It is expected that both graphs are trees. The left
vertex is expected
to be the root of the current graph, while the right
vertex is the root
of the graph being merged into the current one.
source§impl Sodg
impl Sodg
sourcepub fn add(&mut self, v1: u32) -> Result<()>
pub fn add(&mut self, v1: u32) -> Result<()>
Add a new vertex v1
to itself.
For example:
use sodg::Sodg;
let mut g = Sodg::empty();
g.add(0).unwrap();
g.add(42).unwrap();
g.bind(0, 42, "hello").unwrap();
If vertex v1
already exists in the graph, Ok
will be returned.
sourcepub fn bind(&mut self, v1: u32, v2: u32, a: &str) -> Result<()>
pub fn bind(&mut self, v1: u32, v2: u32, a: &str) -> Result<()>
Make an edge e1
from vertex v1
to vertex v2
and put a
label on it.
For example:
use sodg::Sodg;
let mut g = Sodg::empty();
g.add(0).unwrap();
g.add(42).unwrap();
g.bind(0, 42, "forward").unwrap();
g.bind(42, 0, "backward").unwrap();
If an edge with this label already exists, it will be replaced with a new edge.
If either vertex v1
or v2
is absent, an Err
will be returned.
If v1
equals to v2
, an Err
will be returned.
The label a
can’t be empty. If it is empty, an Err
will be returned.
sourcepub fn put(&mut self, v: u32, d: Hex) -> Result<()>
pub fn put(&mut self, v: u32, d: Hex) -> Result<()>
Set vertex data.
For example:
use sodg::Hex;
use sodg::Sodg;
let mut g = Sodg::empty();
g.add(42).unwrap();
g.put(42, Hex::from_str_bytes("hello, world!")).unwrap();
If vertex v1
is absent, an Err
will be returned.
sourcepub fn data(&mut self, v: u32) -> Result<Hex>
pub fn data(&mut self, v: u32) -> Result<Hex>
Read vertex data, and then submit the vertex to garbage collection.
For example:
use sodg::Hex;
use sodg::Sodg;
let mut g = Sodg::empty();
g.add(42).unwrap();
let data = Hex::from_str_bytes("hello, world!");
g.put(42, data.clone()).unwrap();
assert_eq!(data, g.data(42).unwrap());
#[cfg(feature = "gc")]
assert!(g.is_empty());
If vertex v1
is absent, an Err
will be returned.
If there is no data, an empty Hex
will be returned, for example:
use sodg::Sodg;
let mut g = Sodg::empty();
g.add(42).unwrap();
assert!(g.data(42).unwrap().is_empty());
sourcepub fn kids(&self, v: u32) -> Result<Vec<(String, u32)>>
pub fn kids(&self, v: u32) -> Result<Vec<(String, u32)>>
Find all kids of a vertex.
For example:
use sodg::Sodg;
let mut g = Sodg::empty();
g.add(0).unwrap();
g.add(42).unwrap();
g.bind(0, 42, "k").unwrap();
let (a, to) = g.kids(0).unwrap().first().unwrap().clone();
assert_eq!("k", a);
assert_eq!(42, to);
If vertex v1
is absent, None
will be returned.
Just in case, if you need to put all names into a single line:
use itertools::Itertools;
use sodg::Sodg;
let mut g = Sodg::empty();
g.add(0).unwrap();
g.add(42).unwrap();
g.bind(0, 42, "a").unwrap();
g.bind(0, 42, "b").unwrap();
g.bind(0, 42, "c").unwrap();
assert_eq!("a,b,c", g.kids(0).unwrap().into_iter().map(|(a, _)| a).collect::<Vec<String>>().join(","));
sourcepub fn kid(&self, v: u32, a: &str) -> Option<u32>
pub fn kid(&self, v: u32, a: &str) -> Option<u32>
Find a kid of a vertex, by its edge name, and return the ID of the vertex found.
For example:
use sodg::Sodg;
let mut g = Sodg::empty();
g.add(0).unwrap();
g.add(42).unwrap();
g.bind(0, 42, "k").unwrap();
assert_eq!(42, g.kid(0, "k").unwrap());
If vertex v1
is absent, None
will be returned.
source§impl Sodg
impl Sodg
sourcepub fn slice(&mut self, loc: &str) -> Result<Sodg>
pub fn slice(&mut self, loc: &str) -> Result<Sodg>
Take a slice of the graph, keeping only the vertex specified by the locator and its kids, recursively found in the entire graph.
sourcepub fn slice_some(
&mut self,
loc: &str,
p: fn(_: u32, _: u32, _: String) -> bool
) -> Result<Sodg>
pub fn slice_some( &mut self, loc: &str, p: fn(_: u32, _: u32, _: String) -> bool ) -> Result<Sodg>
Take a slice of the graph, keeping only the vertex specified by the locator and its kids, recursively found in the entire graph, but only if the provided predicate agrees with the selection of the kids.
source§impl Sodg
impl Sodg
sourcepub fn to_xml(&self) -> Result<String>
pub fn to_xml(&self) -> Result<String>
Make XML graph.
For example, for this code:
use sodg::Hex;
use sodg::Sodg;
let mut g = Sodg::empty();
g.add(0).unwrap();
g.put(0, Hex::from_str_bytes("hello")).unwrap();
g.add(1).unwrap();
g.bind(0, 1, "foo").unwrap();
g.bind(0, 1, "bar").unwrap();
let xml = g.to_xml().unwrap();
println!("{}", xml);
The printout will look like this:
<?xml version="1.1" encoding="UTF-8"?>
<sodg>
<v id="0">
<e a="foo" to="1" />
<e a="bar" to="1" />
<data>68 65 6C 6C 6F</data>
</v>
<v id="1" />
</sodg>