use cuddle_release::ui::{DynUi, Ui}; use std::{ io::Write, sync::{Arc, Mutex}, }; struct BufferInner { pub stdout: Vec, pub stderr: Vec, } impl BufferInner { fn write_str(&mut self, content: &str) { write!(&mut self.stdout, "{}", content).unwrap(); } fn write_err_str(&mut self, content: &str) { write!(&mut self.stderr, "{}", content).unwrap(); } fn write_str_ln(&mut self, content: &str) { writeln!(&mut self.stdout, "{}", content).unwrap(); } fn write_err_str_ln(&mut self, content: &str) { writeln!(&mut self.stderr, "{}", content).unwrap(); } } #[derive(Clone)] pub struct BufferUi { inner: Arc>, } impl BufferUi { pub fn get_stdout(&self) -> String { let inner = self.inner.lock().unwrap(); let output = std::str::from_utf8(&inner.stdout).unwrap(); output.to_string() } pub fn get_stderr(&self) -> String { let inner = self.inner.lock().unwrap(); let output = std::str::from_utf8(&inner.stderr).unwrap(); output.to_string() } pub fn get_output(&self) -> (String, String) { let inner = self.inner.lock().unwrap(); let stdout = std::str::from_utf8(&inner.stdout).unwrap(); let stderr = std::str::from_utf8(&inner.stderr).unwrap(); (stdout.to_string(), stderr.to_string()) } } impl Ui for BufferUi { fn write_str(&self, content: &str) { let mut inner = self.inner.lock().unwrap(); print!("{}", content); inner.write_str(content) } fn write_err_str(&self, content: &str) { let mut inner = self.inner.lock().unwrap(); eprint!("{}", content); inner.write_err_str(content) } fn write_str_ln(&self, content: &str) { let mut inner = self.inner.lock().unwrap(); println!("{}", content); inner.write_str_ln(content) } fn write_err_str_ln(&self, content: &str) { let mut inner = self.inner.lock().unwrap(); eprintln!("{}", content); inner.write_err_str_ln(content) } } impl Default for BufferInner { fn default() -> Self { Self { stdout: Vec::new(), stderr: Vec::new(), } } } impl Default for BufferUi { fn default() -> Self { Self { inner: Arc::new(Mutex::new(BufferInner::default())), } } } impl From for DynUi { fn from(value: BufferUi) -> Self { Box::new(value) } } impl From<&BufferUi> for DynUi { fn from(value: &BufferUi) -> Self { value.clone().into() } }