seed
seed copied to clipboard
Proposal: Redirect println! to console.log
Redirect println! and similar functions to console.log.
Motivation:
- We can use standard Rust functions for logging / debugging.
- It will be easier for beginners to learn and play with Seed.
- We don't need to maintain our custom
console.logwrappers.
Inspiration for implementation: https://github.com/DeMille/wasm-glue
This is a very good idea, it would simplify web development with seed a lot! Especially if the dbg!() macro works as well
That'd be great; didn't think it was possible. The log! macro's still useful for showing multiple things, and error for showing red text in the console, but native rust println! is a better default.
Agreed on this.
News:
- github.com/DeMille/wasm-glue
- Overrides standard macros so I think we can't / don't want to use it.
- github.com/Stebalien/gag-rs
- Not usable at the moment.
- Required Rust function for stdout redirection exists, but it's undocumented and unstable. See related rust-lang tracking issue for more info (above this comment).
Nice research. Want to close this one until a later later time? I don't have any insight on how to implement.
@David-OConnor I suggest to leave it open for a few days so other guys can see this issue and Rust developers know that we (WASM app developers) want this feature.
Any updates on this?
Any updates on this?
See https://github.com/DeMille/wasm-glue/issues/3 and https://github.com/rust-lang/rust/issues/31343#issuecomment-812636785.
So I've implemented custom println & eprintln in MoonZoon. This way you get at least a compilation error when those custom methods are in scope imported by zoon::* to prevent silent fails. I'm not sure if we want it in Seed, log! is good enough I think.
Unfortunately writing a Rust RFC to make native println-like functions work isn't my priority. Also we should take into account std::fmt may increase Wasm file size a lot so I'm not sure how it should be actually implemented to be universal enough (to support more lightweight fmt machinery).
I'd love to see this too. FWIW, it's possible to hack this redirection today in nightly Rust:
#![feature(internal_output_capture)]
#[wasm_bindgen]
pub fn start() {
let z = Arc::new(Mutex::new(Vec::new()));
let mut idx = 0usize;
/// This redirects all stderr and stdout to the buffer contained in `z`.
std::io::set_output_capture(Some(z.clone()));
println!("Hello, world!");
let x = z.lock().unwrap();
let prev_idx = idx;
idx = x.len();
let z = std::str::from_utf8(&x[prev_idx..idx]).unwrap();
log(&z);
}
I'm experimenting with a loop that would offload the de-buffering to a webworker so it happens continuously in the background.
That said, it feels like the proper solution is a wasm32-unknown-browser target that would (IMO correctly) direct println! to console.log
Consider also supplying an implementation of the log crate traits, like this:
/// A simple implementation of [`log::Log`].
pub struct SeedLogger;
impl SeedLogger {
/// Initialise the logger.
///
/// You must only call this once in an application!
pub fn init() -> Result<(), SetLoggerError> {
log::set_logger(&SeedLogger).map(|_| log::set_max_level(FILTER))
}
}
impl log::Log for SeedLogger {
fn enabled(&self, metadata: &Metadata<'_>) -> bool {
metadata.level() <= LEVEL
}
fn log(&self, record: &Record<'_>) {
let m = record.metadata();
if self.enabled(m) {
let target = m.target();
seed::log!(format!("[{}] ({}) {}", m.level(), target, record.args()));
}
}
fn flush(&self) {}
}
obsolete since v0.10.0