From 8100785702d96cb3236f4b2eaf901127c7831a06 Mon Sep 17 00:00:00 2001 From: Christopher Hock Date: Tue, 16 Jan 2024 14:33:24 +0100 Subject: [PATCH] Repackage output to crate form(#11) * Repackage output to crate form * Add name argument for CLI * Add template files, fix standard input --- Cargo.toml | 2 +- src/bindgen.rs | 75 ++++++++++++++++++++++++++++--- src/main.rs | 7 ++- src/templates/Cargo.toml.template | 17 +++++++ src/templates/lib.rs.template | 11 +++++ 5 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 src/templates/Cargo.toml.template create mode 100644 src/templates/lib.rs.template diff --git a/Cargo.toml b/Cargo.toml index 422694b..fdadb43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" description = "A yaml-to-rust code generator for generating Rust code from yaml config files e.g. as found in openAPI." readme = "README.md" repository = "https://github.com/The-Nazara-Project/Thanix" -license = "MIT" +license = "GPL-3.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/bindgen.rs b/src/bindgen.rs index f66ade3..a138469 100644 --- a/src/bindgen.rs +++ b/src/bindgen.rs @@ -1,6 +1,11 @@ use serde::Deserialize; use serde_yaml::{Number, Value}; -use std::{collections::HashMap, fs::File, io::Write}; +use std::{ + collections::HashMap, + env::{current_dir, set_current_dir}, + fs::{self, File}, + io::Write, +}; #[derive(Debug, Deserialize)] #[allow(dead_code)] @@ -96,6 +101,59 @@ struct Property { all_of: Option>, } +/// Create all necessary structures and directories for the crate. +/// Requires `output` folder to exist. +/// +/// # Arguments +/// +/// - `output_name: &str` - The name of the output library given by the CLI. Default `output/`. +/// +/// # Panics +/// +/// This function panics when the `output/` directory does not exist. +fn create_lib_dir(output_name: &str) -> Result<(), Box> { + println!("Starting repackaging into crate..."); + let source_files = ["paths.rs", "types.rs"]; + + if !fs::metadata(output_name).is_ok() { + panic!("Fatal: Output directory does not exist!"); + } + + std::env::set_current_dir(output_name)?; + + for src_file in &source_files { + if !fs::metadata(src_file).is_ok() { + panic!("Source file {} does not exist!", src_file); + } + } + + let src_dir = "src"; + fs::create_dir_all(&src_dir)?; + + for src_file in source_files { + let dest_path = format!("{}/{}", src_dir, src_file); + fs::rename(src_file, &dest_path)?; + } + + let mut lib_file = fs::File::create(format!("{}/lib.rs", src_dir))?; + write!(lib_file, "{}", include_str!("templates/lib.rs.template"))?; + + let cargo_toml = format!(include_str!("templates/Cargo.toml.template"), output_name); + + fs::write("Cargo.toml", cargo_toml)?; + + let readme_contents = r#" +# Readme + +This output was automatically generated by `Thanix` (github.com/The-Nazara-Project/Thanix). +"#; + + fs::write("README.md", readme_contents)?; + + println!("Output successfully repackaged!"); + Ok(()) +} + /// Makes a comment out of a given string. fn make_comment(input: String, indent: usize) -> String { return input @@ -189,16 +247,16 @@ fn if_some(this: Option, func: F) { } /// Generates the Rust bindings from a file. -pub fn gen(input_path: impl AsRef) { +pub fn gen(input_path: impl AsRef, output_name: String) { // Parse the schema. let input = std::fs::read_to_string(input_path).unwrap(); let yaml: Schema = serde_yaml::from_str(&input).unwrap(); // Generate output folder. - _ = std::fs::create_dir("output/"); + _ = std::fs::create_dir(&output_name); // Create and open the output file for structs. - let mut types_file = File::create("output/types.rs").unwrap(); + let mut types_file = File::create(output_name.clone() + "/types.rs").unwrap(); // For every struct. for (name, comp) in &yaml.components.schemas { @@ -268,7 +326,7 @@ pub fn gen(input_path: impl AsRef) { } // Create and open the output file for paths. - let mut paths_file = File::create("output/paths.rs").unwrap(); + let mut paths_file = File::create(output_name.clone() + "/paths.rs").unwrap(); // For every path. for (name, path) in &yaml.paths { @@ -298,4 +356,11 @@ pub fn gen(input_path: impl AsRef) { .unwrap() }); } + + _ = match create_lib_dir(&output_name) { + Ok(()) => (), + Err(e) => { + panic!("{}", e); + } + }; } diff --git a/src/main.rs b/src/main.rs index 4344dc3..5bd8313 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,9 @@ struct Args { /// Path to a YAML schema file. #[arg(short, long)] input_file: Option, + /// Name of the output package (Default 'output') + #[arg(short, long)] + name: Option, } fn main() { @@ -26,13 +29,13 @@ fn main() { // Welcome Message println!( "{} \n(c) The Nazara Project. (github.com/The-Nazara-Project)\n - Licensed under the terms of the MIT-License.\n\ + Licensed under the terms of the GPL-v3.0-License.\n\ Check github.com/The-Nazara-Project/Thanix/LICENSE for more info.\n", ascii_art ); match args.input_file { - Some(file) => bindgen::gen(file), + Some(file) => bindgen::gen(file, args.name.unwrap_or("output".to_owned())), None => println!("Error: You need to provide a YAML schema to generate from."), } } diff --git a/src/templates/Cargo.toml.template b/src/templates/Cargo.toml.template new file mode 100644 index 0000000..2243e93 --- /dev/null +++ b/src/templates/Cargo.toml.template @@ -0,0 +1,17 @@ +[package] +name = "{}" +version = "0.1.0" +authors = ["Your Name"] +edition = "2021" + +[lib] +path = "src/lib.rs" + +[dependencies] +serde = {{ version = ">1.0.195", features = ["derive"] }} +serde_yaml = ">0.9.30" +reqwest = {{ version = ">0.*", features = ["blocking", "json"] }} + +[[bin]] +name = "your_bin_name" +path = "src/main.rs" \ No newline at end of file diff --git a/src/templates/lib.rs.template b/src/templates/lib.rs.template new file mode 100644 index 0000000..54ca92c --- /dev/null +++ b/src/templates/lib.rs.template @@ -0,0 +1,11 @@ +// Your library code goes here. +#[macro_use] +extern crate serde_derive; + +extern crate serde; +extern crate serde_json; +extern crate url; +extern crate reqwest; + +pub mod paths; +pub mod types; \ No newline at end of file