use crate::cargo_cmds::CargoCmds;
use std::io;
#[derive(Clone)]
pub struct Repl {
pub body: Vec<String>,
cursor: usize,
cargo_cmds: CargoCmds,
}
impl Repl {
pub fn new() -> Self {
Self {
body: vec!["fn main() {\n".to_string(), "}".to_string()],
cursor: 1,
cargo_cmds: Default::default(),
}
}
pub fn insert(&mut self, mut input: String) {
input.insert(0, '\t');
input.push('\n');
self.body.insert(self.cursor, input);
self.cursor += 1;
}
pub fn reset(&mut self) {
self.prepare_ground().expect("Error while resetting Repl");
*self = Self::new();
}
pub fn show(&self) -> String {
format!("Current Repl Code:\n{}", self.body.join(""))
}
pub fn prepare_ground(&self) -> Result<(), io::Error> {
self.cargo_cmds.cargo_new()?;
Ok(())
}
pub fn eval(&self, input: String) -> io::Result<String> {
let eval_statement = format!("println!(\"{{:?}}\", {{\n{}\n}});", input);
let mut repl = self.clone();
repl.insert(eval_statement);
let code = repl.body.join("");
Ok(self.cargo_cmds.cargo_run(code)?)
}
pub fn add_dep(&self, dep: &[String]) -> std::io::Result<std::process::Child> {
Ok(self.cargo_cmds.cargo_add(dep)?)
}
pub fn build(&self) -> std::io::Result<std::process::Child> {
self.cargo_cmds.cargo_build()
}
}