//mod component; pub use self::component::*; mod engine; pub use self::engine::*; mod input; pub use self::input::*; mod output; pub use self::output::*; pub mod tui; pub use std::error::Error; /// Standard result type. pub type Usually = Result>; /// Standard optional result type. pub type Perhaps = Result, Box>; #[cfg(test)] #[test] fn test_stub_engine () -> Usually<()> { struct TestEngine(bool); struct TestInput(bool); struct TestOutput([u16;4]); enum TestEvent { Test1 } impl Engine for TestEngine { type Input = TestInput; type Handled = (); type Output = TestOutput; type Unit = u16; type Size = [u16;2]; type Area = [u16;4]; fn exited (&self) -> bool { self.0 } } impl Input for TestInput { type Event = TestEvent; fn event (&self) -> &Self::Event { &TestEvent::Test1 } fn is_done (&self) -> bool { self.0 } fn done (&self) {} } impl Output for TestOutput { fn area (&self) -> [u16;4] { self.0 } fn area_mut (&mut self) -> &mut [u16;4] { &mut self.0 } fn render_in (&mut self, _: [u16;4], _: &dyn Render) -> Usually<()> { Ok(()) } } impl Render for String { fn min_size (&self, _: [u16;2]) -> Perhaps<[u16;2]> { Ok(Some([self.len() as u16, 1])) } } Ok(()) } #[cfg(test)] #[test] fn test_tui_engine () -> Usually<()> { use crate::tui::*; use std::sync::{Arc, RwLock}; struct TestComponent(String); impl Content for TestComponent { fn content (&self) -> Option> { Some(&self.0) } } impl Handle for TestComponent { fn handle (&mut self, from: &TuiInput) -> Perhaps { Ok(None) } } let engine = Tui::new()?; engine.read().unwrap().exited.store(true, std::sync::atomic::Ordering::Relaxed); let state = TestComponent("hello world".into()); let state = std::sync::Arc::new(std::sync::RwLock::new(state)); engine.run(&state)?; Ok(()) }