#![doc = include_str!("../README.md")]
extern crate core;
mod experimental;
pub mod graph;
pub mod operation;
pub mod semantics;
#[cfg(feature = "serde")]
mod serde;
pub mod util;
use crate::util::InternString;
use ::serde::{Deserialize, Serialize};
use derive_more::From;
pub use graph::EdgeInsertionOrder;
pub use graph::EdgeKey;
pub use graph::Graph;
pub use graph::NodeKey;
pub use semantics::Semantics;
#[derive(derive_more::Debug, Clone, Copy, PartialEq, Eq, Hash, From)]
#[debug("P({_0})")]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SubstMarker(pub InternString);
interned_string_newtype!(SubstMarker);
pub mod prelude {
pub use super::SubstMarker;
pub use crate::graph::{Graph, NodeKey};
pub use crate::operation::builder::{BuilderOpLike, OperationBuilder};
pub use crate::operation::builtin::LibBuiltinOperation;
pub use crate::operation::signature::OperationSignature;
pub use crate::operation::signature::parameter::{GraphWithSubstitution, OperationParameter};
pub use crate::operation::signature::parameterbuilder::OperationParameterBuilder;
pub use crate::operation::user_defined::{AbstractNodeId, UserDefinedOperation};
pub use crate::operation::{
BuiltinOperation, Operation, OperationContext, OperationId, run_from_concrete,
};
pub use crate::semantics::{
AbstractGraph, AbstractJoin, AbstractMatcher, ConcreteGraph, ConcreteToAbstract, Semantics,
};
}
#[cfg(test)]
mod tests {
use super::*;
use crate::graph::dot::DotCollector;
fn child_order() {
let mut collector = DotCollector::new();
let mut graph = Graph::<&str, ()>::new();
macro_rules! c {
() => {
collector.collect(&graph);
};
}
c!();
let a = graph.add_node("hello");
c!();
let b = graph.add_node("world");
c!();
graph.add_edge(a, b, ());
c!();
let next_edge = graph.next_outgoing_edge(a, (a, b));
assert_eq!(next_edge, (a, b));
let prev_edge = graph.prev_outgoing_edge(a, (a, b));
assert_eq!(prev_edge, (a, b));
let c = graph.add_node("foo");
c!();
graph.add_edge(a, c, ());
c!();
let next_edge = graph.next_outgoing_edge(a, (a, b));
assert_eq!(next_edge, (a, c));
let prev_edge = graph.prev_outgoing_edge(a, (a, c));
assert_eq!(prev_edge, (a, b));
let prev_edge = graph.prev_outgoing_edge(a, (a, b));
assert_eq!(prev_edge, (a, c));
let d = graph.add_node("bar");
c!();
graph.add_edge(a, d, ());
c!();
let next_edge = graph.next_outgoing_edge(a, (a, c));
assert_eq!(next_edge, (a, d));
let next_edge = graph.next_outgoing_edge(a, (a, d));
assert_eq!(next_edge, (a, b));
let prev_edge = graph.prev_outgoing_edge(a, (a, b));
assert_eq!(prev_edge, (a, d));
let before_b = graph.add_node("before_b");
c!();
graph.add_edge_ordered(
a,
before_b,
(),
EdgeInsertionOrder::Prepend,
EdgeInsertionOrder::Append,
);
c!();
let after_d = graph.add_node("after_d");
c!();
graph.add_edge_ordered(
a,
after_d,
(),
EdgeInsertionOrder::Append,
EdgeInsertionOrder::Append,
);
c!();
let next_edge = graph.next_outgoing_edge(a, (a, b));
assert_eq!(next_edge, (a, c));
let prev_edge = graph.prev_outgoing_edge(a, (a, b));
assert_eq!(prev_edge, (a, before_b));
let next_edge = graph.next_outgoing_edge(a, (a, d));
assert_eq!(next_edge, (a, after_d));
let prev_edge = graph.prev_outgoing_edge(a, (a, before_b));
assert_eq!(prev_edge, (a, after_d));
let dot = collector.finalize();
println!("{}", dot);
assert!(false);
}
}