Skip to content

Commit

Permalink
Repackage output to crate form(#11)
Browse files Browse the repository at this point in the history
* Repackage output to crate form

* Add name argument for CLI

* Add template files, fix standard input
  • Loading branch information
ByteOtter authored Jan 16, 2024
1 parent c7af834 commit 8100785
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
75 changes: 70 additions & 5 deletions src/bindgen.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down Expand Up @@ -96,6 +101,59 @@ struct Property {
all_of: Option<Vec<Value>>,
}

/// 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<dyn std::error::Error>> {
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
Expand Down Expand Up @@ -189,16 +247,16 @@ fn if_some<F: FnOnce(&T), T>(this: Option<T>, func: F) {
}

/// Generates the Rust bindings from a file.
pub fn gen(input_path: impl AsRef<std::path::Path>) {
pub fn gen(input_path: impl AsRef<std::path::Path>, 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 {
Expand Down Expand Up @@ -268,7 +326,7 @@ pub fn gen(input_path: impl AsRef<std::path::Path>) {
}

// 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 {
Expand Down Expand Up @@ -298,4 +356,11 @@ pub fn gen(input_path: impl AsRef<std::path::Path>) {
.unwrap()
});
}

_ = match create_lib_dir(&output_name) {
Ok(()) => (),
Err(e) => {
panic!("{}", e);
}
};
}
7 changes: 5 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ struct Args {
/// Path to a YAML schema file.
#[arg(short, long)]
input_file: Option<String>,
/// Name of the output package (Default 'output')
#[arg(short, long)]
name: Option<String>,
}

fn main() {
Expand All @@ -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."),
}
}
17 changes: 17 additions & 0 deletions src/templates/Cargo.toml.template
Original file line number Diff line number Diff line change
@@ -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"
11 changes: 11 additions & 0 deletions src/templates/lib.rs.template
Original file line number Diff line number Diff line change
@@ -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;

0 comments on commit 8100785

Please sign in to comment.