+use std::sync::{Arc, Mutex};
+use std::io::Write;
+
+pub trait Output : Clone + 'static {
+ fn locked_write(&self, data: &[u8]);
+}
+
+#[derive(Clone)]
+pub struct DevNull {}
+impl Output for DevNull {
+ fn locked_write(&self, _data: &[u8]) {}
+}
+#[derive(Clone)]
+pub struct StringBuffer(Arc<Mutex<String>>);
+impl Output for StringBuffer {
+ fn locked_write(&self, data: &[u8]) {
+ self.0.lock().unwrap().push_str(&String::from_utf8(data.to_vec()).unwrap());
+ }
+}
+impl StringBuffer {
+ pub fn new() -> Self {
+ Self(Arc::new(Mutex::new(String::new())))
+ }
+ pub fn into_string(self) -> String {
+ Arc::try_unwrap(self.0).unwrap().into_inner().unwrap()
+ }
+}
+
+pub struct TestLogger<Out : Output> {