use std::ffi::OsStr; use std::fs; use std::io; use std::option::Option; use std::path::{Path, PathBuf}; use imgui; use rlua::Lua; #[derive(Default, PartialEq)] pub struct Test { pub path: PathBuf, text: Option, } impl Test { pub fn new(path: PathBuf) -> Test { Test { path: path, text: None, } } pub fn read(&mut self) -> &str { if self.text.is_none() { self.text = Some(fs::read_to_string(&self.path).expect("Failed to read file")); } return self.text.as_ref().unwrap(); } pub fn text(&self) -> &str { return match &self.text { Some(text) => text, None => "", } } } #[derive(Default)] pub struct Bench { lua: Lua, tests: Vec, tests_path: PathBuf, selected_test: Option, console: Vec, } impl Bench { pub fn new() -> Bench { /* Prepare lua environment */ let lua = Lua::new(); let lua_setup = lua.context(|context| -> rlua::Result<()> { use rlua::{String, Variadic}; let globals = context.globals(); let ui_table = context.create_table()?; let ui_print = context.create_function(|_, strings: Variadic| { Ok(()) })?; ui_table.set("print", ui_print)?; globals.set("ui", ui_table)?; Ok(()) }); // TODO: handle errors // if let Err(e) = lua_setup {} let mut b = Bench { lua: lua, tests: Vec::new(), tests_path: PathBuf::from("lua"), selected_test: None, console: Vec::new(), }; // TODO: set graphically and use RV b.load_tests(); return b; } pub fn load_tests(&mut self) -> io::Result<()> { let entries: Result, io::Error> = fs::read_dir(&self.tests_path)? .into_iter() .map(|r| r.map(|f| f.path())) .collect(); match entries { Ok(files) => { self.tests = files .into_iter() .filter(|f| f.is_file()) .filter(|f| f.extension().unwrap_or(OsStr::new("")) == "lua") .map(|f| Test::new(f)) .collect(); return Ok(()); } Err(e) => return Err(e), } } pub fn draw(&mut self, _: &mut bool, ui: &mut imgui::Ui) { use imgui::*; let win = Window::new(im_str!("Testbench")) .size([400., 500.], Condition::Appearing) .position([20., 20.], Condition::Appearing); win.build(&ui, || { for (index, test) in self.tests.iter().enumerate() { if let Some(test_name) = test.path.to_str() { let test_name: ImString = test_name.to_string().into(); let selected = matches!(self.selected_test, Some(i) if i == index); if Selectable::new(&test_name).selected(selected).build(ui) { self.selected_test = Some(index) } } } ui.separator(); if let Some(index) = self.selected_test { if let Some(test_name) = self.tests[index].path.to_str() { let imstr: ImString = format!("Selected Test: {}", test_name).to_string().into(); ui.text_wrapped(&imstr); ui.same_line(0.); if ui.button(im_str!("Run"), [0., 0.]) { self.run_test(index); } ui.same_line(0.); if ui.button(im_str!("Show"), [0., 0.]) { self.show_test(index); } } } ui.separator(); ChildWindow::new("console") .size([0., 0.]) .scrollable(true) .build(&ui, || { for line in &self.console { ui.text(line); } }); }); } fn run_test(&mut self, index: usize) { if let Some(test) = self.tests.get_mut(index) { let text = test.read(); let mut output = imgui::ImString::new(""); self.lua.context( |context| match context.load(text).eval::() { Ok(values) => { output.push_str( &values .iter() .map(|value| format!("{:?}", value)) .collect::>() .join("\t"), ); } Err(e) => { output.push_str(&e.to_string()); } }, ); self.console.push(output); } } fn show_test(&self, index: usize) {} }