use std::env::temp_dir;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use std::process::Command;
use crate::utils::stdout_and_stderr;
#[derive(Clone)]
pub struct CargoCmds {
tmp_dir: PathBuf,
irust_dir: PathBuf,
main_file: PathBuf,
}
impl Default for CargoCmds {
fn default() -> Self {
let tmp_dir = temp_dir();
let irust_dir = {
let mut dir = tmp_dir.clone();
dir.push("irust");
dir
};
let main_file = {
let mut dir = irust_dir.clone();
dir.push("src/main.rs");
dir
};
Self {
tmp_dir,
irust_dir,
main_file,
}
}
}
impl CargoCmds {
pub fn cargo_new(&self) -> Result<(), io::Error> {
self.clean_toml();
if Path::new(&self.irust_dir).exists() {
std::fs::remove_dir_all(&self.irust_dir)?;
}
let _ = Command::new("cargo")
.current_dir(&*self.tmp_dir)
.args(&["new", "irust"])
.output();
self.cargo_build()?.wait()?;
Ok(())
}
pub fn cargo_run(&self, code: String) -> Result<String, io::Error> {
let mut main = File::create(&*self.main_file)?;
write!(main, "{}", code)?;
Ok(stdout_and_stderr(
Command::new("cargo")
.current_dir(&*self.irust_dir)
.arg("run")
.output()?,
))
}
pub fn cargo_add(&self, dep: &[String]) -> io::Result<std::process::Child> {
self.soft_clean()?;
Ok(Command::new("cargo")
.current_dir(&*self.irust_dir)
.arg("add")
.args(dep)
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.spawn()?)
}
pub fn cargo_build(&self) -> Result<std::process::Child, io::Error> {
Ok(Command::new("cargo")
.current_dir(&*self.irust_dir)
.arg("build")
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.spawn()?)
}
fn clean_toml(&self) {
use std::fs::File;
use std::io::Read;
let mut clean = String::new();
let toml_file = {
let mut f = self.irust_dir.clone();
f.push("Cargo.toml");
f
};
if !Path::exists(&toml_file) {
return;
}
let mut toml_read = File::open(&toml_file).unwrap();
let toml_contents = {
let mut c = String::new();
toml_read.read_to_string(&mut c).unwrap();
c
};
for line in toml_contents.lines() {
clean.push_str(line);
if line.contains("[dependencies]") {
break;
}
clean.push('\n')
}
let mut toml_write = File::create(&toml_file).unwrap();
write!(toml_write, "{}", clean).unwrap();
}
fn soft_clean(&self) -> io::Result<()> {
let mut main = std::fs::File::create(&self.main_file)?;
let main_src = "fn main() {}";
write!(main, "{}", main_src)?;
Ok(())
}
}