Struct sodg::Sodg

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

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

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.

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

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.

Find an object by the provided locator and print its tree of sub-objects and edges.

The function is mostly used for testing.

Merge another graph into itself.

Is it empty?

Emptiness means that not a single vertex is in the graph.

For example:

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 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.

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.

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.

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

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, 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.

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

Find a kid of a vertex, by its edge name, and return the ID of the vertex found and the locator of the edge.

For example:

use sodg::Sodg;
let mut g = Sodg::empty();
g.add(0).unwrap();
g.add(42).unwrap();
g.bind(0, 42, "k/foo").unwrap();
assert_eq!((42, "foo".to_string()), g.kid_and_loc(0, "k").unwrap());

If vertex v1 is absent, None will be returned.

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

Check whether data is in the vertex.

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.

Save the entire Sodg into a binary file.

The entire Sodg can be restored from the file. The function 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 graph, 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.