Announcing dot-writer, a library for writing Graphviz DOT graphs

I published a crate called dot-writer! Very exciting, it's my first open source sortie. Its a library for writing graphs in the Graphviz DOT language, so you can write rust code like this:

 use dot_writer::{Color, DotWriter, Attributes, Shape, Style};

 let mut output_bytes = Vec::new();
 {
     let mut writer = DotWriter::from(&mut output_bytes);
     writer.set_pretty_print(false);
     let mut digraph = writer.digraph();
     {
         let mut cluster = digraph.cluster();
         cluster.set_style(Style::Filled);
         cluster.set_color(Color::LightGrey);
         cluster.node_attributes()
             .set_style(Style::Filled)
             .set_color(Color::White);
         cluster.edge("a0", "a1").edge("a2").edge("a3");
         cluster.set_label("process #1");
         // cluster goes out of scope here to write closing bracket
     }
     {
         let mut cluster = digraph.cluster();
         cluster.node_attributes()
             .set_style(Style::Filled);
         cluster.edge("b0", "b1").edge("b2").edge("b3");
         cluster.set_label("process #2");
         cluster.set_color(Color::Blue);
         // cluster goes out of scope here to write closing bracket
     }
     digraph.edge("start", "a0");
     digraph.edge("start", "b0");
     digraph.edge("a1", "b3");
     digraph.edge("b2", "a3");
     digraph.edge("a3", "a0");
     digraph.edge("a3", "end");
     digraph.edge("b3", "end");
     digraph.node_named("start")
         .set_shape(Shape::Mdiamond);
     digraph.node_named("end")
         .set_shape(Shape::Msquare);
     // digraph goes out of scope here to write closing bracket
     // then writer goes out of scope here to free up output_bytes for reading
 }
 println!("{}", std::str::from_utf8(output_bytes).unwrap());

To write DOT like this:

digraph {
  subgraph cluster_0 {
    style="filled";
    color=lightgray;
    node [style="filled", color=white];
    a0->a1->a2->a3;
    label="process #1";
  }
  subgraph cluster_1 {
    node [style="filled"];
    b0->b1->b2->b3;
    label="process #2";
    color=blue;
  }
  start->a0;
  start->b0;
  a1->b3;
  b2->a3;
  a3->a0;
  a3->end;
  b3->end;
  start [shape=Mdiamond];
  end [shape=Msquare];
}

Then it can be rendered with the dot executable (not part of this library) to create a lovely graph like this:

Complex example graph

As I mention, my first crate / open source library, so hoping to get some feedback on anything I might have missed :slight_smile:

6 Likes

That is a very creative concept! It certainly doesn't look like idiomatic rust, but with the comments explaining how you're using Drop, it makes enough sense. Good work!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.