Struct sodg::Sodg

source ·
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§

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.

Disable all alerts.

Enable all alerts. This function also runs all vertices through all checks and returns the list of errors found. If everything was fine, an empty vector is returned.

Check all alerts for the given list of vertices. If any of them have any issues, Err is returned.

Makes an empty Sodg, with no vertices and no edges.

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.

Finds an object by the provided locator and prints its tree of sub-objects and edges. Mostly used for testing.

Merge this new graph into itself.

Is it empty?

use sodg::Sodg;
let mut sodg = Sodg::empty();
sodg.add(0).unwrap();
sodg.add(42).unwrap();
sodg.bind(0, 42, "hello").unwrap();

Get next unique ID of a vertex. This ID will never be returned by next() again. Also, this ID will not be equal to any of the existing IDs of vertices.

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.

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.

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.

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());

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(","));

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, "π"));

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, "π"));

Save the entire Sodg into a binary file. The entire Sodg can be restored from the file. Returns the size of the file just saved.

Load the entire Sodg from a binary file previously created by save().

Take a slice of the Sodg, keeping only the vertex specified by the locator.

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>

Trait Implementations§

Formats the value using the given formatter. Read more
Deserialize this value from the given Serde deserializer. Read more
Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.