diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..3243a6e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "weblog" +version = "0.1.0" +authors = ["Rob Watson "] +edition = "2018" +description = "weblog is a crate that defines a set of macros for calling `console.log()` and other members of the browser's console API when targeting Wasm." +repository = "https://github.com/rfwatson/weblog" +keywords = ["wasm", "webassembly", "console", "log", "logging"] +license = "MIT OR Apache-2.0" + +[lib] +# FIXME: `cargo test` refuses to cross-compile doctests, even with `-Zdoctest-xcompile`. +# E.g.: `cargo test --target wasm32-unknown-unknown -Zdoctest-xcompile` +test = false +doctest = true + +[features] +default = ["web_sys"] +web_sys = ["web-sys", "paste"] +std_web = ["stdweb"] + +[dependencies] +web-sys = { version = "*", optional = true, features = ["console"] } +stdweb = { version = "*", optional = true } +paste = { version = "1.0", optional = true } diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3f8d698 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +docs: + cargo doc --all --no-deps --target wasm32-unknown-unknown && cargo doc --open diff --git a/README.md b/README.md new file mode 100644 index 0000000..d167161 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# Weblog + +weblog is a crate that defines a set of macros for calling `console.log()`, `console.error()` and other members of the browser's console API when targeting Wasm. + +### Features + +* Supports `web-sys` and `stdweb` backends with an identical public API +* Support for variadic arguments on all calls +* No stringification before sending to the browser - log entire objects and use the full introspective debugging power of the browser console. + +## Usage + +```toml +# Defaults to web-sys +weblog = "0.1" + +# For stdweb: +weblog = { version = "0.1", default-features = false, features = ["std_web"] } +``` + +See the documentation for usage examples. + +The crate currently exposes the following macros: + +* `console_clear!` +* `console_debug!` +* `console_dir!` +* `console_dirxml!` +* `console_error!` +* `console_info!` +* `console_log!` +* `console_trace!` +* `console_warn!` + +## License + +Licensed under MIT or Apache-2. + diff --git a/src/console/mod.rs b/src/console/mod.rs new file mode 100644 index 0000000..4bfbcc9 --- /dev/null +++ b/src/console/mod.rs @@ -0,0 +1,5 @@ +#[cfg(feature = "web_sys")] +pub mod web_sys; + +#[cfg(feature = "std_web")] +pub mod std_web; diff --git a/src/console/std_web.rs b/src/console/std_web.rs new file mode 100644 index 0000000..1b1f17c --- /dev/null +++ b/src/console/std_web.rs @@ -0,0 +1,74 @@ +pub extern crate stdweb; +pub use stdweb::js; + +#[doc = "Call the browser's `console.debug()` function."] +#[macro_export] +macro_rules! console_debug { + ($( $item:expr ),* ) => {{ + $crate::stdweb::js! { console.debug($( @{$item} ),*) } + }}; +} + +#[doc = "Call the browser's `console.clear()` function."] +#[macro_export] +macro_rules! console_clear { + ($item:expr) => {{ + $crate::stdweb::js! { console.clear() } + }}; +} + +#[doc = "Call the browser's `console.dir()` function."] +#[macro_export] +macro_rules! console_dir { + ($( $item:expr ),* ) => {{ + $crate::stdweb::js! { console.dir($( @{$item} ),*) } + }}; +} + +#[doc = "Call the browser's `console.dirxml()` function."] +#[macro_export] +macro_rules! console_dirxml { + ($( $item:expr ),* ) => {{ + $crate::stdweb::js! { console.dirxml($( @{$item} ),*) } + }}; +} + +#[doc = "Call the browser's `console.error()` function."] +#[macro_export] +macro_rules! console_error { + ($( $item:expr ),* ) => {{ + $crate::stdweb::js! { console.error($( @{$item} ),*) } + }}; +} + +#[doc = "Call the browser's `console.info()` function."] +#[macro_export] +macro_rules! console_info { + ($( $item:expr ),* ) => {{ + $crate::stdweb::js! { console.info($( @{$item} ),*) } + }}; +} + +#[doc = "Call the browser's `console.log()` function."] +#[macro_export] +macro_rules! console_log { + ($( $item:expr ),* ) => {{ + $crate::stdweb::js! { console.log($( @{$item} ),*) } + }}; +} + +#[doc = "Call the browser's `console.trace()` function."] +#[macro_export] +macro_rules! console_trace { + ($( $item:expr ),* ) => {{ + $crate::stdweb::js! { console.trace($( @{$item} ),*) } + }}; +} + +#[doc = "Call the browser's `console.warn()` function."] +#[macro_export] +macro_rules! console_warn { + ($( $item:expr ),* ) => {{ + $crate::stdweb::js! { console.warn($( @{$item} ),*) } + }}; +} diff --git a/src/console/web_sys.rs b/src/console/web_sys.rs new file mode 100644 index 0000000..51e5c0a --- /dev/null +++ b/src/console/web_sys.rs @@ -0,0 +1,79 @@ +#[doc(hidden)] +pub extern crate web_sys; + +use paste::paste; + +macro_rules! websys_rules { + ($level:ident) => { + paste! { + #[doc = "Call the browser's `console." $level "()` function.\n\n\ + The web-sys crate accepts up to a maximum of seven arguments, all of which must implement `Into`.\n\n\ + See the [wasm-bindgen documentation](../wasm_bindgen/struct.JsValue.html) for more information."] + #[macro_export] + macro_rules! [] { + () => { + $crate::web_sys::console::[<$level _0>]() + }; + ($a:expr) => { + $crate::web_sys::console::[<$level _1>](&$a.into()) + }; + ($a:expr, $b:expr) => { + $crate::web_sys::console::[<$level _2>](&$a.into(), &$b.into()) + }; + ($a:expr, $b:expr, $c:expr) => { + $crate::web_sys::console::[<$level _3>](&$a.into(), &$b.into(), &$c.into()) + }; + ($a:expr, $b:expr, $c:expr, $d:expr) => { + $crate::web_sys::console::[<$level _4>](&$a.into(), &$b.into(), &$c.into(), &$d.into()) + }; + ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr) => { + $crate::web_sys::console::[<$level _5>]( + &$a.into(), + &$b.into(), + &$c.into(), + &$d.into(), + &$e.into(), + ) + }; + ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr) => { + $crate::web_sys::console::[<$level _6>]( + &$a.into(), + &$b.into(), + &$c.into(), + &$d.into(), + &$e.into(), + &$f.into(), + ) + }; + ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr, $g:expr) => { + $crate::web_sys::console::[<$level _7>]( + &$a.into(), + &$b.into(), + &$c.into(), + &$d.into(), + &$e.into(), + &$f.into(), + &$g.into(), + ) + }; + } + } + } +} + +websys_rules!(debug); +websys_rules!(dir); +websys_rules!(dirxml); +websys_rules!(error); +websys_rules!(info); +websys_rules!(log); +websys_rules!(trace); +websys_rules!(warn); + +#[doc = "Call the browser's `console.clear()` function."] +#[macro_export] +macro_rules! console_clear { + () => { + $crate::web_sys::console::clear() + }; +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..21b2e36 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,83 @@ +//! weblog is a crate that defines a set of macros for calling `console.log()`, `console.error()` +//! and other members of the browser's console API when targeting Wasm. +//! +//! # Features +//! +//! * Supports `web-sys` and `stdweb` backends with an identical public API +//! * Support for variadic arguments on all calls +//! * No stringification before sending to the browser - log entire objects and use the full +//! introspective debugging power of the browser console. +//! +//! # Examples +//! +//! A simple example. +//! +//! ``` +//! # #[macro_use] extern crate weblog; +//! # fn main() { +//! console_log!("Hello world!"); +//! # } +//! ``` +//! Passing multiple arguments is fine too. +//! +//! ``` +//! # #[macro_use] extern crate weblog; +//! # fn main() { +//! console_log!("Foo", "bar", "baz"); +//! # } +//! ``` +//! All of the common browser log levels are supported. +//! +//! ``` +//! # #[macro_use] extern crate weblog; +//! # fn main() { +//! console_debug!("Just testing..."); +//! console_warn!("...but then..."); +//! console_error!("...something bad happened."); +//! # } +//! ``` +//! It's possible to send more than just strings or `&str`s: +//! +//! ``` +//! # #[macro_use] extern crate weblog; +//! # fn main() { +//! console_log!( +//! "&str", +//! "string".to_string(), +//! 1, +//! 2.0, +//! 3f32, +//! true, +//! false +//! ); +//! # } +//! ``` +//! When using `web-sys` crate the macros accept any value that implements the `Into` trait. See [JsValue](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/struct.JsValue.html) for +//! more details. +//! +//! No stringification is performed on the Rust side - so objects will be fully introspectable in +//! the browser's console! +//! +//! # Usage +//! +//! By default, the crate assumes the presence of the `web-sys` crate. +//! +//! ```toml +//! weblog = "0.1" +//! ``` +//! +//! +//! If you'd prefer to use it +//! with `stdweb`, enable the feature in `Cargo.toml`: +//! +//! ```toml +//! weblog = { version = "0.1", default-features = false, features = ["stdweb"] } +//! ``` +//! +mod console; + +#[cfg(feature = "web_sys")] +pub use self::console::web_sys::*; + +#[cfg(feature = "std_web")] +pub use self::console::std_web::*;