forky_web/logging/
log_buffer.rs

1use forky_core::prelude::*;
2use js_sys::Function;
3use js_sys::Reflect;
4use wasm_bindgen::prelude::Closure;
5use wasm_bindgen::JsCast;
6use wasm_bindgen::JsValue;
7
8pub struct LogBuffer {
9	name: &'static str,
10	log: RcCell<String>,
11	// _closure: Closure<dyn FnMut(JsValue)>,
12	func: Function,
13}
14
15impl LogBuffer {
16	// this breaks panics
17	// pub fn new_err() -> Self { Self::new("error") }
18	pub fn new_log() -> Self { Self::new("log") }
19	pub fn get_log(&self) -> std::cell::RefMut<'_, String> {
20		self.log.borrow_mut()
21	}
22	pub fn new(name: &'static str) -> Self {
23		let log = rccell(String::new());
24		let log2 = log.clone();
25
26		let closure: Closure<dyn FnMut(JsValue)> =
27			Closure::new(move |val: JsValue| {
28				if let Some(mut val) = val.as_string() {
29					val.push('\n');
30					log2.borrow_mut().push_str(val.as_str());
31				}
32			});
33		let func = Self::get_func(name);
34		Self::set_func(name, closure.as_ref().unchecked_ref());
35
36		Self {
37			name,
38			log,
39			// _closure,
40			func,
41		}
42	}
43	fn get_func(name: &str) -> Function {
44		let window = web_sys::window().unwrap();
45		let console = Reflect::get(&window, &"console".into()).unwrap();
46		let func = Reflect::get(&console, &name.into()).unwrap();
47		func.into()
48	}
49	fn set_func(name: &str, func: &JsValue) {
50		let window = web_sys::window().unwrap();
51		let console = Reflect::get(&window, &"console".into()).unwrap();
52		Reflect::set(&console, &name.into(), func).unwrap();
53	}
54
55	pub fn end(self) -> String { (*self.log.borrow()).clone() }
56}
57
58impl Drop for LogBuffer {
59	fn drop(&mut self) { Self::set_func(self.name, &self.func.clone().into()); }
60}