Crates.io | rust_dot |
lib.rs | rust_dot |
version | 0.6.0 |
source | src |
created_at | 2024-02-18 15:43:27.239051 |
updated_at | 2024-05-03 08:06:43.392654 |
description | RustDOT is mostly the Graphviz DOT language, lightly rustified. |
homepage | |
repository | https://sourceforge.net/projects/rust-dot/ |
max_upload_size | |
id | 1144160 |
size | 41,759 |
RustDOT is mostly the Graphviz DOT language, lightly rustified. It can be embedded as a macro or parsed from a string or file. The purpose is extracting the stucture. Layout hints are currently out of scope.
let g1 = rust_dot! {
graph {
A -- B -- C; /* semicolon is optional */
"B" -- D // quotes not needed here
}
};
println!("{} {} \"{}\" {:?} {:?}", g1.strict, g1.directed, g1.name, g1.nodes, g1.edges);
// false false "" ["A", "B", "C", "D"] [(0, 1), (1, 2), (1, 3)]
let g2 = parse_string("digraph Didi { -1 -> 2 -> .3 2 -> 4.2 }");
println!("{} {} \"{}\" {:?} {:?}", g2.strict, g2.directed, g2.name, g2.nodes, g2.edges);
// false true "Didi" ["-1", "2", ".3", "4.2"] [(0, 1), (1, 2), (1, 3)]
The return values can be fed to crates petgraph
:
let mut petgraph = petgraph::graph::Graph::new();
let nodes: Vec<_> = rust_dot_graph.nodes
.iter()
.map(|node| petgraph
.add_node(node))
.collect();
for edge in rust_dot_graph.edges {
petgraph
.add_edge(nodes[edge.0], nodes[edge.1], ());
};
or graph
/graph_builder
:
use graph::prelude::*;
let graph: DirectedCsrGraph<usize> = GraphBuilder::new()
.csr_layout(CsrLayout::Sorted)
.edges(rust_dot_graph.edges)
.build();
This is work in progress. Nothing is stabilised!
Implement strict
, it is currently ignored/skipped
Return Err instead of panicking on wrong input
Put Spans on Lexemes, based on their input, maybe using crate macroex
Separate return type (currently Parser
, which should be internal)
Implement node attributes, they are currently ignored/skipped
Implement node defaults
Implement edge attributes, they are currently ignored/skipped
Implement edge defaults
Deal with graph attributes, with and without keyword graph
Reimplement rust_dot
as a proc-macro, transforming its input as const at compile time
As an extension to DOT, allow label or weight to come from a Rust expression
As an extension to DOT, allow label or weight to come from invoking a closure
Rust macros are tokenised by the Rust lexer, which is subtly different from Graphviz. For consistency (and ease of
implementation) the parse_*
functions use the same lexer. These are the consequences:
parse_*
functions may also be UTF-16 or Latin-1.
You must deal with other encodings yourself.<<I>"</I> <B> )}] [{( </B> \\>
<<I>"<!--"--></I> <B><!--"--> )}] [{( <!--"--></B> <!--"-->\\<!--"-->>
[,;.:!?]
(incomplete and wrong for some languages.)parse_*
functions work around this, but in [rust_dot!
] you must use raw strings like r"\N"
when they contain unrusty
backslash sequences.#
on the same line is also discarded. Unlike real comments, these are
handled by RustDOT, after lexical analysis. This means that the rest of the line, like the 1st point above,
must be balanced. And it will only end after the closing delimiter, so you should put that on the same line! In
[rust_dot!
] you must use //
instead! (Only the nightly compiler gives access to line numbers in macros.)rust_dot!
]) confusable letters like cyrillic ‘о’ or
rare scripts like runic give warnings.