use databind::Settings;
use serde::Serialize;
use std::fs;
use std::path::{Path, PathBuf};
fn make_pack_mcmeta(description: String, version: u8) -> Result<String, serde_json::Error> {
#[derive(Serialize)]
struct Pack {
pack_format: u8,
description: String,
}
#[derive(Serialize)]
struct PackMcMeta {
pack: Pack,
}
let pack = PackMcMeta {
pack: Pack {
pack_format: version,
description,
},
};
serde_json::to_string(&pack)
}
fn dir_empty(path: &dyn AsRef<Path>) -> std::io::Result<bool> {
Ok(path.as_ref().read_dir()?.next().is_none())
}
pub(crate) fn create_project(args: clap::ArgMatches) -> std::io::Result<()> {
let allowed_chars = "abcdefghijklmnopqrstuvwxyz0123456789_-.";
let name = args.value_of("name").unwrap();
if name.chars().any(|x| !allowed_chars.contains(x)) {
eprintln!("Project name contains disallowed characters");
std::process::exit(1);
}
let description = args.value_of("description").unwrap().to_string();
let base_path = if args.is_present("path") {
args.value_of("path").unwrap()
} else {
name
};
let version: u8 = args.value_of("version").unwrap().parse().unwrap();
let mut path = PathBuf::from(base_path);
let metadata = fs::metadata(&path);
if let Ok(meta) = metadata {
if meta.is_file() || meta.is_dir() && !dir_empty(&path)? {
eprintln!(
"Path {} is an already existant file or non-empty folder",
base_path
);
std::process::exit(1);
}
}
path.push(format!("src/data/{}/functions", name));
fs::create_dir_all(&path)?;
path.push("main.databind");
fs::write(
&path,
"\
func main
tag load
tellraw @a \"Hello, World!\"\n\
end\n",
)?;
path.pop();
path.pop();
path.pop();
path.pop();
let pack_mcmeta = make_pack_mcmeta(description, version)?;
path.push("pack.mcmeta");
fs::write(&path, pack_mcmeta)?;
path.pop();
path.pop();
let databind_toml = toml::to_string(&Settings::default()).unwrap();
path.push("databind.toml");
fs::write(&path, databind_toml)?;
println!(
"Created project {} in {}",
name,
fs::canonicalize(&base_path).unwrap().display()
);
Ok(())
}