pub trait Ui { fn write_str(&self, content: &str); fn write_err_str(&self, content: &str); fn write_str_ln(&self, content: &str); fn write_err_str_ln(&self, content: &str); } pub type DynUi = Box; impl Default for DynUi { fn default() -> Self { Box::::default() } } #[derive(Default)] pub struct ConsoleUi {} #[allow(dead_code)] impl ConsoleUi { pub fn new() -> Self { Self::default() } } impl From for DynUi { fn from(value: ConsoleUi) -> Self { Box::new(value) } } impl Ui for ConsoleUi { fn write_str(&self, content: &str) { print!("{}", content) } fn write_err_str(&self, content: &str) { eprint!("{}", content) } fn write_str_ln(&self, content: &str) { println!("{}", content) } fn write_err_str_ln(&self, content: &str) { eprintln!("{}", content) } }