use std::fs;
use std::path::Path;
use csharp_binder::{CSharpBuilder, CSharpConfiguration};
fn read_file(path: &Path) -> Result<String, String> {
let content = fs::read_to_string(path).map_err(|x| x.to_string())?;
if content.contains("extern \"C\"") || content.contains("\n#[repr(") {
return Ok(content);
}
Err("There is nothing to export here".to_string())
}
fn capitalcase_word<S: AsRef<str>>(input: S) -> String {
let first = input
.as_ref()
.chars()
.next()
.unwrap()
.to_uppercase()
.to_string();
first
.chars()
.chain(input.as_ref().chars().skip(1))
.collect()
}
fn capitalcase<S: AsRef<str>>(input: S) -> String {
input.as_ref().split('_').map(capitalcase_word).collect()
}
pub fn write_file<S: AsRef<str>>(filename: S, folder: S, content: String) -> Result<(), String> {
let new_filename = capitalcase(filename);
let mut folder = Path::new(folder.as_ref()).to_path_buf();
if !folder.as_path().exists() {
fs::create_dir_all(folder.to_str().unwrap()).map_err(|x| x.to_string())?;
}
folder.push(&new_filename);
folder.set_extension("cs");
fs::write(folder, content).map_err(|x| x.to_string())
}
pub fn generate_csharp<S: AsRef<str>>(
path: S,
dll_name: S,
namespace: &Option<String>,
) -> Result<String, String> {
let path = Path::new(path.as_ref());
let rust_file = read_file(&path)?;
let classname = capitalcase(path.file_stem().unwrap().to_str().unwrap());
let mut configuration = CSharpConfiguration::new(10);
let mut builder = CSharpBuilder::new(&rust_file, dll_name.as_ref(), &mut configuration)
.map_err(|x| x.to_string())?;
if namespace.is_some() {
builder.set_namespace(namespace.as_ref().unwrap());
}
builder.set_type(&classname);
let script = builder.build().map_err(|x| x.to_string())?;
Ok(script)
}
pub fn walk_folder<T: AsRef<str> + PartialEq>(
root: T,
excluded_files: &[String],
) -> Result<Vec<String>, String> {
let p = Path::new(root.as_ref());
if !p.is_dir() {
return Err(format!(
"string provided is not a valid folder: \"{}\"",
root.as_ref()
));
}
let mut results = vec![];
let mut folders_to_check = vec![];
let mut handler = |p, folders_to_check: &mut Vec<_>| {
for entry in fs::read_dir(p).unwrap() {
let entry = entry.unwrap();
let filename = entry.file_name().to_str().unwrap().to_string();
if excluded_files.contains(&filename) {
continue;
}
let e = entry.path().canonicalize().unwrap();
if e.is_file() && e.extension().unwrap_or_default().to_str().unwrap() == "rs" {
results.push(e.to_str().unwrap().to_string())
}
if e.is_dir() {
folders_to_check.push(e);
}
}
};
handler(p.into(), &mut folders_to_check);
loop {
let p = folders_to_check.pop();
if p.is_none() {
break;
}
handler(p.unwrap(), &mut folders_to_check);
}
Ok(results)
}