use crate::GeneratorContext;
use anyhow::anyhow;
use camino::Utf8Path;
use include_dir::{Dir, include_dir};
use toml_edit::{DocumentMut, value};
static SKELETON: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/skeleton");
pub fn generate_cargo_toml(context: &GeneratorContext<'_>) -> anyhow::Result<()> {
let cargo_toml = SKELETON
.get_file("Cargo.toml_")
.or_else(|| SKELETON.get_file("Cargo.toml"))
.ok_or_else(|| anyhow!("Missing Cargo.toml skeleton"))?
.contents_utf8()
.ok_or_else(|| anyhow!("Cargo.toml skeleton is not valid UTF-8"))?;
let mut doc = cargo_toml
.parse::<DocumentMut>()
.map_err(|err| anyhow!("Cargo.toml skeleton is not a valid TOML: {err}"))?;
change_package_name(context, &mut doc);
let output_path = context.output.join("Cargo.toml");
crate::write_if_changed(output_path, doc.to_string())?;
Ok(())
}
fn change_package_name(context: &GeneratorContext, doc: &mut DocumentMut) {
let crate_name = &context.world_name;
doc["package"]["name"] = value(crate_name);
}
const GENERATED_FILES: &[&str] = &["src/lib.rs"];
pub fn copy_skeleton_lock(output: &Utf8Path) -> anyhow::Result<()> {
if let Some(lock_file) = SKELETON.get_file("Cargo.lock") {
let dest = output.join("Cargo.lock");
crate::write_if_changed(dest, lock_file.contents())?;
}
Ok(())
}
pub fn copy_skeleton_sources(output: &Utf8Path) -> anyhow::Result<()> {
if let Some(src) = SKELETON.get_dir("src") {
for file in src.files() {
let src_path = Utf8Path::from_path(file.path())
.ok_or_else(|| anyhow!("Unexpected non-UTF-8 path in skeleton"))?;
if GENERATED_FILES.contains(&src_path.as_str()) {
continue;
}
let dest_path = output.join(src_path);
crate::write_if_changed(dest_path, file.contents())?;
}
recursive_copy_sources(
src.get_dir("src/builtin")
.ok_or_else(|| anyhow!("Missing builtin module in skeleton"))?,
output,
)?;
}
Ok(())
}
fn recursive_copy_sources(dir: &Dir, output: &Utf8Path) -> anyhow::Result<()> {
let dir_path = Utf8Path::from_path(dir.path())
.ok_or_else(|| anyhow!("Unexpected non-UTF-8 path in skeleton"))?;
std::fs::create_dir_all(output.join(dir_path))?;
for file in dir.files() {
let src_path = Utf8Path::from_path(file.path())
.ok_or_else(|| anyhow!("Unexpected non-UTF-8 path in skeleton"))?;
let dest_path = output.join(src_path);
crate::write_if_changed(dest_path, file.contents())?;
}
for dir in dir.dirs() {
recursive_copy_sources(dir, output)?;
}
Ok(())
}