//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_dimensions () { assert_eq!(Area::center(&[10u16, 10, 20, 20]), [20, 20]); } #[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 place (&mut self, _: [u16;4], _: &impl Content) { () } } impl Content for String { fn render (&self, to: &mut TestOutput) { to.area_mut().set_w(self.len() as u16); } } 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.as_str()) } } impl Handle for TestComponent { fn handle (&mut self, from: &TuiIn) -> 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(()) }