pub struct Sodg { /* private fields */ }
Expand description
This struct 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:
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 SODG.
For example, you don’t want more than one edge to depart from any vertex:
use sodg::Sodg;
let mut sodg = Sodg::empty();
sodg.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![];
});
sodg.add(0).unwrap();
sodg.add(1).unwrap();
sodg.add(2).unwrap();
sodg.bind(0, 1, "first").unwrap();
assert!(sodg.bind(0, 2, "second").is_err());
If vertex v1
already exists in the graph, an Err
will be returned.
sourcepub fn alerts_off(&mut self)
pub fn alerts_off(&mut self)
Disable all alerts.
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 closure to provide alternative edge names.
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", &mut DeadRelay::default()).is_err());
let v = g.find(0, "bar", &mut LambdaRelay::new(|v, a, b| {
assert_eq!(a, "bar");
assert_eq!(b, "");
Ok("foo".to_string())
})).unwrap();
assert_eq!(1, v);
If target vertex is not found or v1
is absent,
an Err
will be returned.
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 the Sodg:
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<()>
Makes an edge e1
from vertex v1
to vertex v2
and puts a
label on it.
If the
label is not equal to "ρ"
, makes two backward edges from v2
to v1
and label them as "ρ"
an "𝜎"
.
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’s 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.
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.
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());
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::Hex;
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, String, u32)>>
pub fn kids(&self, v: u32) -> Result<Vec<(String, String, u32)>>
Find all kids of a vertex.
use sodg::Sodg;
let mut g = Sodg::empty();
g.add(0).unwrap();
g.add(42).unwrap();
g.bind(0, 42, "k").unwrap();
let (a, tail, to) = g.kids(0).unwrap().first().unwrap().clone();
assert_eq!("k", a);
assert_eq!("", tail);
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/d.f.e").unwrap();
g.bind(0, 42, "c/hello-world").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.
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());
assert!(g.kid(0, "another").is_none());
If vertex v1
is absent, None
will be returned.
The name of the edge may be a composite of two parts, for example
π/Φ.test
or foo/ν13.print.me
. The parts are separated by the
forward slash. In this case, the search will only take into account
the first part:
use sodg::Sodg;
let mut g = Sodg::empty();
g.add(0).unwrap();
g.add(42).unwrap();
g.bind(0, 42, "π/Φ.test").unwrap();
assert_eq!(Some(42), g.kid(0, "π"));
sourcepub fn loc(&self, v: u32, a: &str) -> Option<String>
pub fn loc(&self, v: u32, a: &str) -> Option<String>
Get a locator of an edge, if it exists.
The name of the edge may be a composite of two parts, for example
π/Φ.foo
or foo/ν6.boom.x.y
. The parts are separated by the
forward slash. This function returns the second part if it exists:
use sodg::Sodg;
let mut g = Sodg::empty();
g.add(0).unwrap();
g.add(42).unwrap();
g.bind(0, 42, "π/Φ.test").unwrap();
assert_eq!(Some("Φ.test".to_string()), g.loc(0, "π"));
assert_eq!(None, g.loc(0, "foo"));
If there is no second part, but the edge is present, an empty string will be returned:
use sodg::Sodg;
let mut g = Sodg::empty();
g.add(0).unwrap();
g.add(42).unwrap();
g.bind(0, 42, "π").unwrap();
assert_eq!(Some("".to_string()), g.loc(0, "π"));
sourcepub fn full(&self, v: u32) -> Result<bool>
pub fn full(&self, v: u32) -> Result<bool>
Check whether data is there.
With this method you can check whether the data is in the vertex:
use sodg::{Hex, Sodg};
let mut g = Sodg::empty();
g.add(0).unwrap();
g.put(0, Hex::from(42)).unwrap();
assert!(g.full(0).unwrap());
If the vertex is absent, the method will return Err
.
source§impl Sodg
impl Sodg
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>