graphviz-rust 0.5.1

The library provides the basic access to the graphs in graphviz format with ability to import into or export from it.
Documentation
### Description

The library provides the basic access to the graphs in [graphviz](https://graphviz.org/) format with ability to import
into or export from it.

### Base examples:

#### Parse dot source

```rust
use dot_generator::*;
use dot_structures::*;

fn parse_test() {
    let g: Graph = parse(
        r#"
        strict digraph t {
            aa[color=green]
            subgraph v {
                aa[shape=square]
                subgraph vv{a2 -> b2}
                aaa[color=red]
                aaa -> bbb
            }
            aa -> be -> subgraph v { d -> aaa}
            aa -> aaa -> v
        }
        "#,
    )
    .unwrap();

    assert_eq!(
        g,
        graph!(strict di id!("t");
          node!("aa";attr!("color","green")),
          subgraph!("v";
            node!("aa"; attr!("shape","square")),
            subgraph!("vv"; edge!(node_id!("a2") => node_id!("b2"))),
            node!("aaa";attr!("color","red")),
            edge!(node_id!("aaa") => node_id!("bbb"))
            ),
          edge!(node_id!("aa") => node_id!("be") => subgraph!("v"; edge!(node_id!("d") => node_id!("aaa")))),
          edge!(node_id!("aa") => node_id!("aaa") => node_id!("v"))
        )
    )
}
```

#### Print graph into dot source

```rust
use dot_generator::*;
use dot_structures::*;
use graphviz_rust::printer::{DotPrinter, PrinterContext};

fn print_test() {
    let mut g = graph!(strict di id!("id"));
    assert_eq!(
        "strict digraph id {}".to_string(),
        g.print(&mut PrinterContext::default())
    );
}
```

#### Transform graph into external formats with cmd engine

```rust
use dot_generator::*;
use dot_structures::*;
use graphviz_rust::{
    attributes::*,
    cmd::{CommandArg, Format},
    exec, parse,
    printer::{DotPrinter, PrinterContext},
};

fn output_test() {
    let mut g = graph!(id!("id");
         node!("nod"),
         subgraph!("sb";
             edge!(node_id!("a") => subgraph!(;
                node!("n";
                NodeAttributes::color(color_name::black), NodeAttributes::shape(shape::egg))
            ))
        ),
        edge!(node_id!("a1") => node_id!(esc "a2"))
    );
    let graph_svg = exec(
        g,
        &mut PrinterContext::default(),
        vec![CommandArg::Format(Format::Svg)],
    )
    .unwrap();
}
```

### Structure:

The structure pursues to follow the dot [notation](https://graphviz.org/doc/info/lang.html) closely, therefore it has
straight accordance. The structures can be found in `dot_structures::*` and has the following denotion:

```text
strict digraph t {                     : graph with t as id
        aa[color=green]                : node aa and attributes in []
        subgraph v {                   : subgraph v
	        aa[shape=square]            : node aa in subgraph
	        subgraph vv{a2 -> b2}       : another subgraph carrying edge inside( a type of the edge is Pair)
	        aaa[color=red]
	        aaa -> subgraph { d -> aaa} : subgraph id is anonymous id
        }
       aa -> be -> d -> aaa            : other edge with a type Chain
   }
```

### Generate a dot structure:

The library provides a set of macros alleviating the process of graph construction.

Most of them, which have the sequence pattern(nodes with attributes, graphs or subgraphs with statements etc.)
have the following syntax:

- name or id or any other markers
- list of structure with a comma or seq of elems with a semicolon

```rust
assert_eq!(
    node!("node_id"; attr!("atr1","val1"),attr!("atr2","val2")),
    node!(
        "node_id",
        vec![attr!("atr1", "val1"), attr!("atr2", "val2")]
    )
);
```

The macros can be found in `dot_generator::*` and has the following denotion:

```rust
fn graph_test() {
    use dot_generator::*;
    use dot_structures::*;

    let g = r#"
            strict digraph t {
                aa[color=green]
                subgraph v {
                    aa[shape=square]
                    subgraph vv{a2 -> b2}
                    aaa[color=red]
                    aaa -> bbb
                }
                aa -> be -> subgraph v { d -> aaa}
                aa -> aaa -> v
            }
            "#;

    graph!(strict di id!("t");
      node!("aa";attr!("color","green")),
      subgraph!("v";
        node!("aa"; attr!("shape","square")),
        subgraph!("vv"; edge!(node_id!("a2") => node_id!("b2"))),
        node!("aaa";attr!("color","red")),
        edge!(node_id!("aaa") => node_id!("bbb"))
        ),
      edge!(node_id!("aa") => node_id!("be") => subgraph!("v"; edge!(node_id!("d") => node_id!("aaa")))),
      edge!(node_id!("aa") => node_id!("aaa") => node_id!("v"))
    );
}
```

### Attributes

The graphviz provides an enormous amount of possible [attributes](https://graphviz.org/doc/info/attrs.html) and to
support it, the library provides a set of structures alleviating the navigation among them namely:

- custom attribute can be easily compound with the macros `attr!(id,id)` nevertheless another possible formats:
- using named attributes like `graphviz_rust::attributes::color` for the `color` attribute
- using the particular
  structures `graphviz_rust::attributes::{EdgeAttributes,SubgraphAttributes GraphAttributes, NodeAttributes}`
  grouping and displaying which attribute belongs to the struct.

```rust
use dot_generator::*;
use dot_structures::*;
use graphviz_rust::attributes::{
    color, color_name, GraphAttributes, NodeAttributes,
};
use into_attr::IntoAttribute;

fn test() {
    assert_eq!(GraphAttributes::center(true), attr!("center", true));
    assert_eq!(
        NodeAttributes::color(color_name::antiquewhite1),
        attr!("color", "antiquewhite1")
    );
    assert_eq!(color::default().into_attr(), attr!("color", "black"));
}
```

### Transform into string following a dot format

The trait `DotPrinter` is summoned to transform a graph structure into string.

```rust
use dot_generator::*;
use dot_structures::*;
use graphviz_rust::printer::{DotPrinter, PrinterContext};

fn subgraph_test() {
    let mut ctx = PrinterContext::default();
    let s =
        subgraph!("id"; node!("abc"), edge!(node_id!("a") => node_id!("b")));

    assert_eq!(
        s.print(&mut ctx),
        "subgraph id {\n    abc\n    a -- b \n}".to_string()
    );
}
```

The module allows adjusting some parameters such as indent step or line separator using `PrinterContext`:

```rust
fn ctx() {
    use self::graphviz_rust::printer::PrinterContext;
    let mut ctx = PrinterContext::default();

    ctx.always_inline(); // everything in one line
    ctx.with_semi(); // semicolon at the end of every element
    ctx.with_indent_step(4); // indent 4 (default 2)
    ctx.with_inline_size(60); // size indicating the line needs to break into multilines
}
```

### External formats and others using cmd engine

The library provides an ability to use [command commands](https://graphviz.org/doc/info/command.html) from the rust
code.
The details are denoted in `graphviz_rust::{exec}` and `graphviz_rust::{exec_dot}` methods

```rust
fn output_test() {
    let mut g = graph!(id!("id"));
    exec(
        g,
        PrinterContext::default(),
        vec![
            CommandArg::Format(Format::Svg),
            CommandArg::Output("path_to_file".to_string()),
        ],
    );
}
```

### Caveats

#### The [command client]https://graphviz.org/download/ should be installed

Since, the library operates with a cmd client to execute the commands, the client should be installed beforehand, otherwise, the errors like: `No file or directory found` or `program not found` (depending on the OS) will be popped up.