use std::convert::Infallible; use std::io::{self, IsTerminal}; use std::rc::Rc; use std::time::Instant; use avril_core::{Extension, Op}; use avril_ext_stdio::Stdio; /// Whether inspected values written to this stream should be colored. pub fn colors(stderr: bool) -> bool { let terminal = if stderr { io::stderr().is_terminal() } else { io::stdout().is_terminal() }; terminal && std::env::var_os("NO_COLOR").is_none_or(|value| value.is_empty()) } pub fn init(stdio: Rc) -> Extension { let clear = stdio.clone(); let start = Instant::now(); Extension { name: "ext:console", dependencies: &[], ops: vec![ Op::new("op_console_print", move |(stderr, text): (bool, String)| { stdio.print(stderr, text) }), Op::new("op_console_clear", move |_: ()| { if io::stdout().is_terminal() { clear.print(false, "\x1b[1;1H\x1b[0J".into())?; } Ok::<_, io::Error>(()) }), Op::new("op_console_colors", |stderr: bool| { Ok::<_, Infallible>(colors(stderr)) }), Op::new("op_console_now", move |_: ()| { Ok::<_, io::Error>(start.elapsed().as_secs_f64() * 1000.0) }), ], modules: &[ ( "ext:console/main.js", include_str!(concat!(env!("OUT_DIR"), "/main.js")), ), ( "ext:console/inspect.js", include_str!(concat!(env!("OUT_DIR"), "/inspect.js")), ), ( "ext:console/format.js", include_str!(concat!(env!("OUT_DIR"), "/format.js")), ), ( "ext:console/table.js", include_str!(concat!(env!("OUT_DIR"), "/table.js")), ), ], entry_point: Some("ext:console/main.js"), } }