graphviz_rust_bla/cmd.rs
1//! It allows to execute cmd engine passing extra parameters
2//!
3//! *It is important*: to execute it properly it needs to have an [`executable package`] on the system
4//!
5//! The extra information can be found in [`layouts`] and [`outputs`]
6//!
7//! [`layouts`]: https://graphviz.org/docs/layouts/
8//! [`outputs`]:https://graphviz.org/docs/outputs/
9//! [`executable package`]: https://graphviz.org/download/
10//! # Example:
11//! ```no_run
12//! use dot_structures::*;
13//! use dot_generator::*;
14//! use graphviz_rust::attributes::*;
15//! use graphviz_rust::cmd::{CommandArg, Format};
16//! use graphviz_rust::exec;
17//! use graphviz_rust::printer::{PrinterContext,DotPrinter};
18//!
19//! fn graph_to_output(){
20//! let mut g = graph!(id!("id");
21//! node!("nod"),
22//! subgraph!("sb";
23//! edge!(node_id!("a") => subgraph!(;
24//! node!("n";
25//! NodeAttributes::color(color_name::black), NodeAttributes::shape(shape::egg))
26//! ))
27//! ),
28//! edge!(node_id!("a1") => node_id!(esc "a2"))
29//! );
30//! let graph_svg = exec(g, &mut PrinterContext::default(), vec![
31//! CommandArg::Format(Format::Svg),
32//! ]).unwrap();
33//!
34//! }
35//! fn graph_to_file(){
36//! let mut g = graph!(id!("id"));
37//! let mut ctx = PrinterContext::default();
38//! ctx.always_inline();
39//! let empty = exec(g, &mut ctx, vec![
40//! CommandArg::Format(Format::Svg),
41//! CommandArg::Output("1.svg".to_string())
42//! ]).unwrap();
43//!
44//! }
45//! ```
46use tempfile::NamedTempFile;
47use std::io::{self, Error, Write};
48use std::process::{Command, Output};
49use std::str;
50
51pub(crate) fn exec(graph: String, args: Vec<CommandArg>) -> io::Result<String> {
52 let args = args.into_iter().map(|a| a.prepare()).collect();
53 temp_file(graph).and_then(|f| {
54 let path = f.path().to_string_lossy().to_string();
55 do_exec(path, args).map(|o| {
56 if o.status.code().map(|c| c != 0).unwrap_or(true) {
57 String::from_utf8_lossy(&*o.stderr).to_string()
58 } else {
59 String::from_utf8_lossy(&*o.stdout).to_string()
60 }
61 })
62 })
63}
64
65
66fn do_exec(input: String, args: Vec<String>) -> std::io::Result<Output> {
67 let mut command = Command::new("dot");
68
69 for arg in args {
70 command.arg(arg);
71 }
72 command
73 .arg(input)
74 .output()
75}
76
77fn temp_file(ctx: String) -> io::Result<NamedTempFile> {
78 let mut file = NamedTempFile::new()?;
79 file.write_all(ctx.as_bytes())
80 .map(|_x| file)
81}
82
83/// Command arguments that can be passed to exec.
84/// The list of possible [`commands`]
85///
86/// [`commands`]:https://graphviz.org/doc/info/command.html
87pub enum CommandArg {
88 /// any custom argument.
89 ///
90 /// _Note_: it does not manage any prefixes and thus '-' or the prefix must be passed as well.
91 Custom(String),
92 /// Regulates the output file with -o prefix
93 Output(String),
94 /// [`Layouts`] in cmd
95 ///
96 /// [`Layouts`]: https://graphviz.org/docs/layouts/
97 Layout(Layout),
98 /// [`Output`] formats in cmd
99 ///
100 /// [`Output`]:https://graphviz.org/docs/outputs/
101 Format(Format),
102}
103
104impl CommandArg {
105 fn prepare(&self) -> String {
106 match self {
107 CommandArg::Custom(s) => s.clone(),
108 CommandArg::Output(p) => format!("-o{}", p),
109 CommandArg::Layout(l) => format!("-K{}", format!("{:?}", l).to_lowercase()),
110 CommandArg::Format(f) => {
111 let str = match f {
112 Format::Xdot12 => "xdot1.2".to_string(),
113 Format::Xdot14 => "xdot1.4".to_string(),
114 Format::ImapNp => "imap_np".to_string(),
115 Format::CmapxNp => "cmapx_np".to_string(),
116 Format::DotJson => "dot_json".to_string(),
117 Format::XdotJson => "xdot_json".to_string(),
118 Format::PlainExt => "plain-ext".to_string(),
119 _ => format!("{:?}", f).to_lowercase()
120 };
121 format!("-T{}", str)
122 }
123 }
124 }
125}
126
127#[derive(Debug)]
128pub enum Layout {
129 Dot,
130 Neato,
131 Twopi,
132 Circo,
133 Fdp,
134 Asage,
135 Patchwork,
136 Sfdp,
137}
138
139
140#[derive(Debug)]
141pub enum Format {
142 Bmp,
143 Cgimage,
144 Canon,
145 Dot,
146 Gv,
147 Xdot,
148 Xdot12,
149 Xdot14,
150 Eps,
151 Exr,
152 Fig,
153 Gd,
154 Gd2,
155 Gif,
156 Gtk,
157 Ico,
158 Cmap,
159 Ismap,
160 Imap,
161 Cmapx,
162 ImapNp,
163 CmapxNp,
164 Jpg,
165 Jpeg,
166 Jpe,
167 Jp2,
168 Json,
169 Json0,
170 DotJson,
171 XdotJson,
172 Pdf,
173 Pic,
174 Pct,
175 Pict,
176 Plain,
177 PlainExt,
178 Png,
179 Pov,
180 Ps,
181 Ps2,
182 Psd,
183 Sgi,
184 Svg,
185 Svgz,
186 Tga,
187 Tif,
188 Tiff,
189 Tk,
190 Vml,
191 Vmlz,
192 Vrml,
193 Vbmp,
194 Webp,
195 Xlib,
196 X11,
197}