152 lines
4.2 KiB
Rust
152 lines
4.2 KiB
Rust
use clap::{Parser, Subcommand};
|
|
use openapi_parser::{build_tree, parse_schema, NodeType, ObjectChild, TreeNode};
|
|
use std::fmt::Write;
|
|
|
|
/// Dump the tree structure of a schema element as dot file
|
|
#[derive(Parser, Debug)]
|
|
#[command(author, version, about, long_about = None)]
|
|
struct Args {
|
|
/// The name of the file to dump
|
|
///
|
|
/// If this value is unspecified, the default petstore schema
|
|
/// is used instead
|
|
#[arg(short, long)]
|
|
file_name: Option<String>,
|
|
|
|
/// The name of the structure to dump
|
|
#[arg(short, long, default_value = "Pet")]
|
|
struct_name: String,
|
|
|
|
/// The action to perform
|
|
#[clap(subcommand)]
|
|
action: Action,
|
|
}
|
|
|
|
#[derive(Subcommand, Debug)]
|
|
enum Action {
|
|
/// Dump as JSON
|
|
Json,
|
|
|
|
/// Dump as Graphviz graph
|
|
Graph,
|
|
|
|
/// Dump as Tex list
|
|
Tex,
|
|
}
|
|
|
|
fn main() {
|
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
|
|
|
let args = Args::parse();
|
|
|
|
let file_content = match args.file_name {
|
|
None => include_str!("../examples/petstore.yaml").to_string(),
|
|
Some(path) => std::fs::read_to_string(path).expect("Unable to load schema file!"),
|
|
};
|
|
|
|
let schema = parse_schema(&file_content);
|
|
let tree = build_tree(&args.struct_name, schema.components.as_ref().unwrap());
|
|
|
|
match args.action {
|
|
Action::Json => println!("{}", serde_json::to_string(&tree).unwrap()),
|
|
Action::Graph => println!("{}", graphviz_export(&tree)),
|
|
|
|
Action::Tex => println!("{}", tex_export(&tree)),
|
|
}
|
|
}
|
|
|
|
fn recurse_export(node: &TreeNode, parent_name: &str, out: &mut String) {
|
|
if !parent_name.is_empty() && matches!(node.r#type, NodeType::Object { .. }) {
|
|
writeln!(out, "\"{}\" -> \"{}\";", parent_name, node.name).unwrap();
|
|
}
|
|
|
|
match &node.r#type {
|
|
NodeType::Array { item } => {
|
|
let mut item = item.clone();
|
|
item.name.push_str(" []");
|
|
recurse_export(&item, parent_name, out);
|
|
}
|
|
NodeType::Object { children, .. } => {
|
|
for child in children {
|
|
recurse_export(&child.node, &node.name, out);
|
|
}
|
|
}
|
|
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn graphviz_export(tree: &TreeNode) -> String {
|
|
let mut out = "digraph G {\n".to_string();
|
|
|
|
recurse_export(tree, "", &mut out);
|
|
|
|
out.push_str("}\n");
|
|
out
|
|
}
|
|
|
|
fn tex_export_inner(tree: &ObjectChild, out: &mut String, required: bool) {
|
|
let type_str = match &tree.node.r#type {
|
|
NodeType::Null => "NULL".to_string(),
|
|
NodeType::Boolean => "bool".to_string(),
|
|
NodeType::Array { item } => format!("{}[]", item.name),
|
|
NodeType::Object { .. } => tree.node.name.to_string(),
|
|
NodeType::String => "string".to_string(),
|
|
NodeType::Number => "number".to_string(),
|
|
NodeType::Integer => "integer".to_string(),
|
|
};
|
|
|
|
write!(out, "\\textbf{{{}}}", tree.name).unwrap();
|
|
if required {
|
|
out.push_str("\\textcolor{red}{*}");
|
|
}
|
|
out.push_str("\n\\newline");
|
|
write!(out, "\\textit{{\\textcolor{{gray}}{{{type_str}}}}}").unwrap();
|
|
|
|
if let Some(description) = &tree.node.description {
|
|
write!(out, "\\newline\n\textcolor{{gray}}{{{}}}", description).unwrap();
|
|
}
|
|
|
|
if let Some(example) = &tree.node.examples.get(0) {
|
|
write!(
|
|
out,
|
|
"\\newline\n\textcolor{{gray}}{{Exemple : {}}}",
|
|
example
|
|
)
|
|
.unwrap();
|
|
}
|
|
}
|
|
|
|
fn tex_export(tree: &TreeNode) -> String {
|
|
let mut out = String::new();
|
|
writeln!(out, "% START OF EXPORT OF STRUCTURE {}", tree.name).unwrap();
|
|
|
|
match &tree.r#type {
|
|
NodeType::Object { children, required } => {
|
|
for child in children {
|
|
tex_export_inner(
|
|
child,
|
|
&mut out,
|
|
required
|
|
.as_ref()
|
|
.map(|r| r.contains(&child.name))
|
|
.unwrap_or(false),
|
|
);
|
|
|
|
out.push_str("\n\n");
|
|
}
|
|
}
|
|
_ => tex_export_inner(
|
|
&ObjectChild {
|
|
name: tree.name.to_string(),
|
|
node: tree.clone(),
|
|
},
|
|
&mut out,
|
|
false,
|
|
),
|
|
}
|
|
|
|
writeln!(out, "% END OF EXPORT OF STRUCTURE {}", tree.name).unwrap();
|
|
out
|
|
}
|