#![allow(clippy::unnecessary_lazy_evaluations, clippy::disallowed_methods, clippy::needless_return)]
use std::{
env, fs::{self, File, OpenOptions}, io, path::{Path, PathBuf}
};
#[derive(Debug)]
pub struct Build {
dir: PathBuf,
}
impl Build {
pub fn new() -> Result<Self, io::Error> {
let mut dir = PathBuf::from(env::var("OUT_DIR").expect("must be called from a build script (build.rs)"));
let out = dir.file_name().unwrap();
assert_eq!(out, "out");
let _ = dir.pop();
let id = dir.file_name().unwrap().to_owned();
assert!(id.to_str().unwrap().starts_with(&format!("{}-", env::var("CARGO_PKG_NAME").unwrap())));
let _ = dir.pop();
let build = dir.file_name().unwrap();
assert_eq!(build, "build");
let _ = dir.pop();
dir.push("resources");
fs::create_dir(&dir).or_else(|e| (e.kind() == io::ErrorKind::AlreadyExists).then(|| ()).ok_or(e)).unwrap();
dir.push(&id);
fs::create_dir(&dir).or_else(|e| (e.kind() == io::ErrorKind::AlreadyExists).then(|| ()).ok_or(e)).unwrap();
env_set("CARGO_RESOURCE_DIR", Path::new("resources").join(id).to_str().unwrap());
Ok(Self { dir })
}
pub fn binaries(&self, images: &[&str]) -> Result<(), io::Error> {
fs::write(self.dir.join("binary"), images.join("\n"))
}
pub fn docker_images(&self, images: &[&str]) -> Result<(), io::Error> {
fs::write(self.dir.join("docker"), images.join("\n"))
}
pub fn path(&self, src: &Path, dest: &Path) -> Result<(), io::Error> {
fs::copy(src, dest).map(drop)
}
pub fn file(&self, mut src: &File, dest: &Path) -> Result<(), io::Error> {
let dest = OpenOptions::new().write(true).create(true).truncate(true).open(self.dir.join(dest))?;
io::copy(&mut src, &mut &dest).map(drop)
}
pub fn clean(&self) -> Result<(), io::Error> {
fs::remove_dir_all(&self.dir)?;
fs::create_dir(&self.dir)
}
pub fn dir(&self) -> &Path {
&self.dir
}
}
pub fn dir_from_out_dir(out_dir: &Path) -> PathBuf {
let mut dir = out_dir.to_owned();
let out = dir.file_name().unwrap();
assert_eq!(out, "out");
let _ = dir.pop();
let package = dir.file_name().unwrap().to_owned();
let _ = dir.pop();
let build = dir.file_name().unwrap();
assert_eq!(build, "build");
let _ = dir.pop();
dir.push("resources");
dir.push(package);
dir
}
#[derive(Debug)]
pub struct Resources {
exe_dir: PathBuf,
res_dir: PathBuf,
}
impl Resources {
pub fn new(resource_dir: &str) -> Result<Self, io::Error> {
let res_dir = PathBuf::from(resource_dir);
let mut exe_dir = env::current_exe()?.parent().unwrap().to_owned();
if exe_dir.ends_with("deps") {
exe_dir = exe_dir.parent().unwrap().to_owned();
}
let res_dir = exe_dir.join(res_dir);
if res_dir.exists() {
Ok(Self { exe_dir, res_dir })
} else {
Err(io::Error::new(io::ErrorKind::NotFound, format!("resource_dir \"{}\" not found", res_dir.display())))
}
}
pub fn binary(&self, binary: &str) -> Result<PathBuf, io::Error> {
let binary_ = self.exe_dir.join(binary);
if binary_.exists() {
Ok(binary_)
} else {
return Err(io::Error::new(io::ErrorKind::NotFound, format!("binary \"{binary}\" not found")));
}
}
pub fn dir(&self) -> &Path {
&self.res_dir
}
}
fn env_set(key: &str, value: &str) {
println!("cargo:rustc-env={key}={value}");
}