1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use forky_core::*;
use js_sys::Function;
use js_sys::Reflect;
use wasm_bindgen::JsCast;
use wasm_bindgen::prelude::Closure;
use wasm_bindgen::JsValue;

pub struct LogBuffer {
	name: &'static str,
	log: RcCell<String>,
	// _closure: Closure<dyn FnMut(JsValue)>,
	func: Function,
}

impl LogBuffer {
	// this breaks panics
	// pub fn new_err() -> Self { Self::new("error") }
	pub fn new_log() -> Self { Self::new("log") }
	pub fn get_log(&self) -> std::cell::RefMut<'_, String> {
		self.log.borrow_mut()
	}
	pub fn new(name: &'static str) -> Self {
		let log = rccell(String::new());
		let log2 = log.clone();

		let closure: Closure<dyn FnMut(JsValue)> =
			Closure::new(move |val: JsValue| {
				if let Some(mut val) = val.as_string() {
					val.push('\n');
					log2.borrow_mut().push_str(val.as_str());
				}
			});
		let func = Self::get_func(name);
		Self::set_func(name, closure.as_ref().unchecked_ref());

		Self {
			name,
			log,
			// _closure,
			func,
		}
	}
	fn get_func(name: &str) -> Function {
		let window = web_sys::window().unwrap();
		let console = Reflect::get(&window, &"console".into()).unwrap();
		let func = Reflect::get(&console, &name.into()).unwrap();
		func.into()
	}
	fn set_func(name: &str, func: &JsValue) {
		let window = web_sys::window().unwrap();
		let console = Reflect::get(&window, &"console".into()).unwrap();
		Reflect::set(&console, &name.into(), func).unwrap();
	}

	pub fn end(self) -> String { (*self.log.borrow()).clone() }
}

impl Drop for LogBuffer {
	fn drop(&mut self) { Self::set_func(self.name, &self.func.clone().into()); }
}