Refactor to proc-macro
This commit is contained in:
parent
944357868c
commit
fce19e049d
|
@ -1,2 +1,2 @@
|
||||||
/target
|
target/
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
|
11
Cargo.toml
11
Cargo.toml
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "weblog"
|
name = "weblog"
|
||||||
version = "0.2.0"
|
version = "0.3.0-beta.1"
|
||||||
authors = ["Rob Watson <rfwatson@users.noreply.github.com>"]
|
authors = ["Rob Watson <rfwatson@users.noreply.github.com>"]
|
||||||
edition = "2018"
|
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."
|
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."
|
||||||
|
@ -15,12 +15,11 @@ doctest = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["web_sys"]
|
default = ["web_sys"]
|
||||||
web_sys = ["js-sys", "paste", "wasm-bindgen", "web-sys"]
|
web_sys = ["web-sys", "wasm-bindgen", "weblog-proc-macro"]
|
||||||
std_web = ["stdweb"]
|
std_web = ["stdweb"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
js-sys = { version = ">= 0.3", optional = true }
|
|
||||||
paste = { version = "1.0", optional = true }
|
|
||||||
stdweb = { version = ">= 0.4", optional = true }
|
stdweb = { version = ">= 0.4", optional = true }
|
||||||
wasm-bindgen = { version = ">= 0.2", optional = true }
|
weblog-proc-macro = { path = "./weblog-proc-macro", version = "0.3.0-beta.1", optional = true }
|
||||||
web-sys = { version = ">= 0.3", optional = true, features = ["console"] }
|
web-sys = { version = "0.3", features = ["console"], optional = true }
|
||||||
|
wasm-bindgen = { version = "0.2", optional = true }
|
||||||
|
|
5
Makefile
5
Makefile
|
@ -1,2 +1,7 @@
|
||||||
|
all: build
|
||||||
|
|
||||||
|
build:
|
||||||
|
cargo build
|
||||||
|
|
||||||
docs:
|
docs:
|
||||||
cargo doc --all --no-deps --target wasm32-unknown-unknown && cargo doc --open
|
cargo doc --all --no-deps --target wasm32-unknown-unknown && cargo doc --open
|
||||||
|
|
12
README.md
12
README.md
|
@ -54,23 +54,31 @@ No stringification is performed on the Rust side - so objects will be fully intr
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
# Defaults to web-sys
|
# Defaults to web-sys
|
||||||
weblog = "0.2"
|
weblog = "0.3.0-beta.1"
|
||||||
|
|
||||||
# For stdweb:
|
# For stdweb:
|
||||||
weblog = { version = "0.2", default-features = false, features = ["std_web"] }
|
weblog = { version = "0.3.0-beta.1", default-features = false, features = ["std_web"] }
|
||||||
```
|
```
|
||||||
|
|
||||||
See the documentation for usage examples.
|
See the documentation for usage examples.
|
||||||
|
|
||||||
The crate currently exposes the following macros:
|
The crate currently exposes the following macros:
|
||||||
|
|
||||||
|
* `console_assert!`
|
||||||
* `console_clear!`
|
* `console_clear!`
|
||||||
|
* `console_count!`
|
||||||
|
* `console_count_reset!`
|
||||||
* `console_debug!`
|
* `console_debug!`
|
||||||
* `console_dir!`
|
* `console_dir!`
|
||||||
* `console_dirxml!`
|
* `console_dirxml!`
|
||||||
* `console_error!`
|
* `console_error!`
|
||||||
|
* `console_exception!`
|
||||||
* `console_info!`
|
* `console_info!`
|
||||||
* `console_log!`
|
* `console_log!`
|
||||||
|
* `console_table!`
|
||||||
|
* `console_time!`
|
||||||
|
* `console_time_end!`
|
||||||
|
* `console_time_stamp!`
|
||||||
* `console_trace!`
|
* `console_trace!`
|
||||||
* `console_warn!`
|
* `console_warn!`
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
/target/
|
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "weblog-example-web-sys"
|
||||||
|
version = "0.3.0-beta.1"
|
||||||
|
authors = ["Rob Watson <rfwatson@users.noreply.github.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
weblog = { path = "../.." }
|
||||||
|
wasm-bindgen = "0.2"
|
|
@ -0,0 +1,7 @@
|
||||||
|
all: build
|
||||||
|
|
||||||
|
build:
|
||||||
|
wasm-pack build --target web --out-name wasm --out-dir ./static
|
||||||
|
|
||||||
|
run:
|
||||||
|
simple-http-server -i static -p 3000 --nocache --try-file ./static/index.html
|
|
@ -0,0 +1,76 @@
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
use weblog::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen(start)]
|
||||||
|
pub fn main() {
|
||||||
|
// A simple example.
|
||||||
|
console_log!("Hello world");
|
||||||
|
|
||||||
|
// Multiple arguments.
|
||||||
|
console_log!("Hello", "there", "world");
|
||||||
|
|
||||||
|
// Various types.
|
||||||
|
console_log!(
|
||||||
|
1.0,
|
||||||
|
2f64,
|
||||||
|
true,
|
||||||
|
"&str",
|
||||||
|
String::from("owned string"),
|
||||||
|
Some("an option"),
|
||||||
|
None as Option<i32>,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Various levels.
|
||||||
|
console_debug!("debug");
|
||||||
|
console_info!("informational");
|
||||||
|
console_warn!("warning");
|
||||||
|
console_error!("an", "error", "occurred");
|
||||||
|
console_exception!("an", "exception", "occurred");
|
||||||
|
|
||||||
|
// Print a stacktrace.
|
||||||
|
console_trace!();
|
||||||
|
|
||||||
|
// And include some data.
|
||||||
|
console_trace!("some", "data", 1, 2, 3);
|
||||||
|
|
||||||
|
// Unlimited arguments.
|
||||||
|
//
|
||||||
|
// Note that due to the design of the web-sys library, passing greater
|
||||||
|
// than 7 variadic arguments (or 8 in the case of console_assert!)
|
||||||
|
// implies a performance hit.
|
||||||
|
console_log!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||||
|
|
||||||
|
// With a trailing comma.
|
||||||
|
console_log!(1,);
|
||||||
|
|
||||||
|
// With no arguments.
|
||||||
|
console_log!();
|
||||||
|
|
||||||
|
// With an assertion.
|
||||||
|
console_assert!(true); // outputs nothing
|
||||||
|
console_assert!(false);
|
||||||
|
console_assert!(false, "Something went wrong");
|
||||||
|
console_assert!(false, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, "Done!");
|
||||||
|
|
||||||
|
// With a simple count.
|
||||||
|
console_count!();
|
||||||
|
console_count_reset!();
|
||||||
|
|
||||||
|
// A count with a label.
|
||||||
|
console_count!("myCounter");
|
||||||
|
console_count!("myCounter");
|
||||||
|
console_count!("myCounter");
|
||||||
|
console_count_reset!("myCounter");
|
||||||
|
|
||||||
|
// A timer.
|
||||||
|
console_time!();
|
||||||
|
console_time_end!();
|
||||||
|
console_time!("with a label");
|
||||||
|
console_time_log!("with a label", "and", 1, "data");
|
||||||
|
console_time_log!("with a label", 1, 2, 3, 4, 5, 6, 7, 8, "data");
|
||||||
|
console_time_end!("with a label");
|
||||||
|
|
||||||
|
// A performance timestamp.
|
||||||
|
console_time_stamp!(); // outputs nothing to console
|
||||||
|
console_time_stamp!("with a label"); // outputs nothing to console
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
*
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Weblog Test</title>
|
||||||
|
<script type="module">
|
||||||
|
import init from "/wasm.js";
|
||||||
|
init();
|
||||||
|
</script>
|
||||||
|
<link rel="shortcut icon" href="#" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Check developer tools console for log messages.</h2>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,5 +1,2 @@
|
||||||
#[cfg(feature = "web_sys")]
|
|
||||||
pub mod web_sys;
|
|
||||||
|
|
||||||
#[cfg(feature = "std_web")]
|
#[cfg(feature = "std_web")]
|
||||||
pub mod std_web;
|
pub mod std_web;
|
||||||
|
|
|
@ -1,26 +1,50 @@
|
||||||
pub extern crate stdweb;
|
pub extern crate stdweb;
|
||||||
pub use stdweb::js;
|
pub use stdweb::js;
|
||||||
|
|
||||||
#[doc = "Call the browser's `console.debug()` function."]
|
#[doc = "Call the browser's `console.assert()` function."]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! console_debug {
|
macro_rules! console_assert {
|
||||||
($( $item:expr ),* ) => {{
|
($($item:expr),* $(,)?) => {{
|
||||||
$crate::stdweb::js! { console.debug($( @{$item} ),*) }
|
$crate::stdweb::js! { console.assert($( @{$item} ),*) }
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc = "Call the browser's `console.clear()` function."]
|
#[doc = "Call the browser's `console.clear()` function."]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! console_clear {
|
macro_rules! console_clear {
|
||||||
($item:expr) => {{
|
($($item:expr),* $(,)?) => {{
|
||||||
$crate::stdweb::js! { console.clear() }
|
$crate::stdweb::js! { console.clear() }
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc = "Call the browser's `console.count()` function."]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! console_count {
|
||||||
|
($($item:expr),* $(,)?) => {{
|
||||||
|
$crate::stdweb::js! { console.count($( @{$item} ),*) }
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "Call the browser's `console.countReset()` function."]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! console_count_reset {
|
||||||
|
($($item:expr),* $(,)?) => {{
|
||||||
|
$crate::stdweb::js! { console.countReset($( @{$item} ),*) }
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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.dir()` function."]
|
#[doc = "Call the browser's `console.dir()` function."]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! console_dir {
|
macro_rules! console_dir {
|
||||||
($( $item:expr ),* ) => {{
|
($($item:expr),* $(,)?) => {{
|
||||||
$crate::stdweb::js! { console.dir($( @{$item} ),*) }
|
$crate::stdweb::js! { console.dir($( @{$item} ),*) }
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
@ -28,7 +52,7 @@ macro_rules! console_dir {
|
||||||
#[doc = "Call the browser's `console.dirxml()` function."]
|
#[doc = "Call the browser's `console.dirxml()` function."]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! console_dirxml {
|
macro_rules! console_dirxml {
|
||||||
($( $item:expr ),* ) => {{
|
($($item:expr),* $(,)?) => {{
|
||||||
$crate::stdweb::js! { console.dirxml($( @{$item} ),*) }
|
$crate::stdweb::js! { console.dirxml($( @{$item} ),*) }
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
@ -36,15 +60,23 @@ macro_rules! console_dirxml {
|
||||||
#[doc = "Call the browser's `console.error()` function."]
|
#[doc = "Call the browser's `console.error()` function."]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! console_error {
|
macro_rules! console_error {
|
||||||
($( $item:expr ),* ) => {{
|
($($item:expr),* $(,)?) => {{
|
||||||
$crate::stdweb::js! { console.error($( @{$item} ),*) }
|
$crate::stdweb::js! { console.error($( @{$item} ),*) }
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc = "Call the browser's `console.exception()` function."]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! console_exception {
|
||||||
|
($($item:expr),* $(,)?) => {{
|
||||||
|
$crate::stdweb::js! { console.exception($( @{$item} ),*) }
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
#[doc = "Call the browser's `console.info()` function."]
|
#[doc = "Call the browser's `console.info()` function."]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! console_info {
|
macro_rules! console_info {
|
||||||
($( $item:expr ),* ) => {{
|
($($item:expr),* $(,)?) => {{
|
||||||
$crate::stdweb::js! { console.info($( @{$item} ),*) }
|
$crate::stdweb::js! { console.info($( @{$item} ),*) }
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
@ -52,15 +84,55 @@ macro_rules! console_info {
|
||||||
#[doc = "Call the browser's `console.log()` function."]
|
#[doc = "Call the browser's `console.log()` function."]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! console_log {
|
macro_rules! console_log {
|
||||||
($( $item:expr ),* ) => {{
|
($($item:expr),* $(,)?) => {{
|
||||||
$crate::stdweb::js! { console.log($( @{$item} ),*) }
|
$crate::stdweb::js! { console.log($( @{$item} ),*) }
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc = "Call the browser's `console.table()` function."]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! console_table {
|
||||||
|
($($item:expr),* $(,)?) => {{
|
||||||
|
$crate::stdweb::js! { console.table($( @{$item} ),*) }
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "Call the browser's `console.time()` function."]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! console_time {
|
||||||
|
($($item:expr),* $(,)?) => {{
|
||||||
|
$crate::stdweb::js! { console.time($( @{$item} ),*) }
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "Call the browser's `console.timeEnd()` function."]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! console_time_end {
|
||||||
|
($($item:expr),* $(,)?) => {{
|
||||||
|
$crate::stdweb::js! { console.timeEnd($( @{$item} ),*) }
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "Call the browser's `console.timeLog()` function."]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! console_time_log {
|
||||||
|
($($item:expr),* $(,)?) => {{
|
||||||
|
$crate::stdweb::js! { console.timeLog($( @{$item} ),*) }
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "Call the browser's `console.timeStamp()` function."]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! console_time_stamp {
|
||||||
|
($($item:expr),* $(,)?) => {{
|
||||||
|
$crate::stdweb::js! { console.timeStamp($( @{$item} ),*) }
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
#[doc = "Call the browser's `console.trace()` function."]
|
#[doc = "Call the browser's `console.trace()` function."]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! console_trace {
|
macro_rules! console_trace {
|
||||||
($( $item:expr ),* ) => {{
|
($($item:expr),* $(,)?) => {{
|
||||||
$crate::stdweb::js! { console.trace($( @{$item} ),*) }
|
$crate::stdweb::js! { console.trace($( @{$item} ),*) }
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
@ -68,7 +140,7 @@ macro_rules! console_trace {
|
||||||
#[doc = "Call the browser's `console.warn()` function."]
|
#[doc = "Call the browser's `console.warn()` function."]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! console_warn {
|
macro_rules! console_warn {
|
||||||
($( $item:expr ),* ) => {{
|
($($item:expr),* $(,)?) => {{
|
||||||
$crate::stdweb::js! { console.warn($( @{$item} ),*) }
|
$crate::stdweb::js! { console.warn($( @{$item} ),*) }
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
use paste::paste;
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub mod __macro {
|
|
||||||
pub use js_sys::Array;
|
|
||||||
pub use wasm_bindgen::JsValue;
|
|
||||||
pub use web_sys::console;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! __jsvalue {
|
|
||||||
($value: expr) => {
|
|
||||||
::std::convert::Into::<$crate::__macro::JsValue>::into($value)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! websys_rules {
|
|
||||||
// $dollar is a workaround to allow repetition in nested macros.
|
|
||||||
// It needs to be the token `$`.
|
|
||||||
($dollar:tt, $level:ident) => {
|
|
||||||
paste! {
|
|
||||||
#[doc = "Call the browser's `console." $level "()` function.\n\n\
|
|
||||||
The web-sys crate accepts any amount of arguments, all of which must implement `Into<JsValue>`.\n\n\
|
|
||||||
See the [wasm-bindgen documentation](../wasm_bindgen/struct.JsValue.html) for more information."]
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! [<console_ $level>] {
|
|
||||||
() => {
|
|
||||||
$crate::__macro::console::[<$level _0>]()
|
|
||||||
};
|
|
||||||
($a:expr $dollar(,)?) => {
|
|
||||||
$crate::__macro::console::[<$level _1>](&$crate::__jsvalue!($a))
|
|
||||||
};
|
|
||||||
($a:expr, $b:expr $dollar(,)?) => {
|
|
||||||
$crate::__macro::console::[<$level _2>](&$crate::__jsvalue!($a), &$crate::__jsvalue!($b))
|
|
||||||
};
|
|
||||||
($a:expr, $b:expr, $c:expr $dollar(,)?) => {
|
|
||||||
$crate::__macro::console::[<$level _3>](&$crate::__jsvalue!($a), &$crate::__jsvalue!($b), &$crate::__jsvalue!($c))
|
|
||||||
};
|
|
||||||
($a:expr, $b:expr, $c:expr, $d:expr $dollar(,)?) => {
|
|
||||||
$crate::__macro::console::[<$level _4>](
|
|
||||||
&$crate::__jsvalue!($a),
|
|
||||||
&$crate::__jsvalue!($b),
|
|
||||||
&$crate::__jsvalue!($c),
|
|
||||||
&$crate::__jsvalue!($d),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
($a:expr, $b:expr, $c:expr, $d:expr, $e:expr $dollar(,)?) => {
|
|
||||||
$crate::__macro::console::[<$level _5>](
|
|
||||||
&$crate::__jsvalue!($a),
|
|
||||||
&$crate::__jsvalue!($b),
|
|
||||||
&$crate::__jsvalue!($c),
|
|
||||||
&$crate::__jsvalue!($d),
|
|
||||||
&$crate::__jsvalue!($e),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr $dollar(,)?) => {
|
|
||||||
$crate::__macro::console::[<$level _6>](
|
|
||||||
&$crate::__jsvalue!($a),
|
|
||||||
&$crate::__jsvalue!($b),
|
|
||||||
&$crate::__jsvalue!($c),
|
|
||||||
&$crate::__jsvalue!($d),
|
|
||||||
&$crate::__jsvalue!($e),
|
|
||||||
&$crate::__jsvalue!($f),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr, $g:expr $dollar(,)?) => {
|
|
||||||
$crate::__macro::console::[<$level _7>](
|
|
||||||
&$crate::__jsvalue!($a),
|
|
||||||
&$crate::__jsvalue!($b),
|
|
||||||
&$crate::__jsvalue!($c),
|
|
||||||
&$crate::__jsvalue!($d),
|
|
||||||
&$crate::__jsvalue!($e),
|
|
||||||
&$crate::__jsvalue!($f),
|
|
||||||
&$crate::__jsvalue!($g),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
($dollar($dollar item:expr),+ $dollar(,)?) => {
|
|
||||||
{
|
|
||||||
let args = ::std::vec![$dollar($crate::__jsvalue!($dollar item)),+];
|
|
||||||
let args = ::std::iter::IntoIterator::into_iter(args).collect::<$crate::__macro::Array>();
|
|
||||||
$crate::__macro::console::$level(&args)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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::__macro::console::clear()
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -64,7 +64,7 @@
|
||||||
//! By default, the crate assumes the presence of the `web-sys` crate.
|
//! By default, the crate assumes the presence of the `web-sys` crate.
|
||||||
//!
|
//!
|
||||||
//! ```toml
|
//! ```toml
|
||||||
//! weblog = "0.1"
|
//! weblog = "0.3"
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
|
@ -72,13 +72,16 @@
|
||||||
//! with `stdweb`, enable the feature in `Cargo.toml`:
|
//! with `stdweb`, enable the feature in `Cargo.toml`:
|
||||||
//!
|
//!
|
||||||
//! ```toml
|
//! ```toml
|
||||||
//! weblog = { version = "0.1", default-features = false, features = ["stdweb"] }
|
//! weblog = { version = "0.3", default-features = false, features = ["stdweb"] }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
mod console;
|
mod console;
|
||||||
|
|
||||||
#[cfg(feature = "web_sys")]
|
#[cfg(feature = "web_sys")]
|
||||||
pub use self::console::web_sys::*;
|
pub use weblog_proc_macro::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "web_sys")]
|
||||||
|
pub use ::web_sys;
|
||||||
|
|
||||||
#[cfg(feature = "std_web")]
|
#[cfg(feature = "std_web")]
|
||||||
pub use self::console::std_web::*;
|
pub use self::console::std_web::*;
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
[package]
|
||||||
|
name = "weblog-proc-macro"
|
||||||
|
version = "0.3.0-beta.1"
|
||||||
|
authors = ["Rob Watson <rfwatson@users.noreply.github.com>"]
|
||||||
|
repository = "https://github.com/rfwatson/weblog"
|
||||||
|
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."
|
||||||
|
edition = "2018"
|
||||||
|
keywords = ["wasm", "webassembly", "console", "log", "logging"]
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
syn = "1.0.41"
|
||||||
|
quote = "1.0.7"
|
||||||
|
proc-macro2 = "1.0"
|
|
@ -0,0 +1,231 @@
|
||||||
|
extern crate proc_macro2;
|
||||||
|
|
||||||
|
mod weblog_impl;
|
||||||
|
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use std::iter;
|
||||||
|
use weblog_impl::{quote_console_func, ArgMode, ConsoleFunc};
|
||||||
|
|
||||||
|
/// Call the browser's `console.assert()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/assert)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_assert(input: TokenStream) -> TokenStream {
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::variadic("assert_with_condition_and_data", 1),
|
||||||
|
iter::once(ArgMode::PassThrough).chain(iter::repeat(ArgMode::IntoJsValue)),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.clear()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/clear)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_clear(input: TokenStream) -> TokenStream {
|
||||||
|
quote_console_func(ConsoleFunc::fixed("clear", 0), iter::empty(), input)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.count()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/count)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_count(input: TokenStream) -> TokenStream {
|
||||||
|
let name = if input.is_empty() {
|
||||||
|
"count"
|
||||||
|
} else {
|
||||||
|
"count_with_label"
|
||||||
|
};
|
||||||
|
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::fixed(name, 1),
|
||||||
|
iter::once(ArgMode::PassThrough),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.countReset()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/countReset)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_count_reset(input: TokenStream) -> TokenStream {
|
||||||
|
let name = if input.is_empty() {
|
||||||
|
"count_reset"
|
||||||
|
} else {
|
||||||
|
"count_reset_with_label"
|
||||||
|
};
|
||||||
|
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::fixed(name, 1),
|
||||||
|
iter::once(ArgMode::PassThrough),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.debug()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/debug)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_debug(input: TokenStream) -> TokenStream {
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::variadic("debug", 0),
|
||||||
|
iter::repeat(ArgMode::IntoJsValue),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.dir()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/dir)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_dir(input: TokenStream) -> TokenStream {
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::variadic("dir", 0),
|
||||||
|
iter::repeat(ArgMode::IntoJsValue),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.dirxml()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/dirxml)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_dirxml(input: TokenStream) -> TokenStream {
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::variadic("dirxml", 0),
|
||||||
|
iter::repeat(ArgMode::IntoJsValue),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.error()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/error)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_error(input: TokenStream) -> TokenStream {
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::variadic("error", 0),
|
||||||
|
iter::repeat(ArgMode::IntoJsValue),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.exception()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/exception)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_exception(input: TokenStream) -> TokenStream {
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::variadic("exception", 0),
|
||||||
|
iter::repeat(ArgMode::IntoJsValue),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.info()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/info)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_info(input: TokenStream) -> TokenStream {
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::variadic("info", 0),
|
||||||
|
iter::repeat(ArgMode::IntoJsValue),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.log()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/log)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_log(input: TokenStream) -> TokenStream {
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::variadic("log", 0),
|
||||||
|
iter::repeat(ArgMode::IntoJsValue),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.table()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/table)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_table(input: TokenStream) -> TokenStream {
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::variadic("table", 0),
|
||||||
|
iter::repeat(ArgMode::IntoJsValue),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.time()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/time)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_time(input: TokenStream) -> TokenStream {
|
||||||
|
let name = if input.is_empty() {
|
||||||
|
"time"
|
||||||
|
} else {
|
||||||
|
"time_with_label"
|
||||||
|
};
|
||||||
|
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::fixed(name, 1),
|
||||||
|
iter::once(ArgMode::PassThrough),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.timeEnd()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/timeEnd)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_time_end(input: TokenStream) -> TokenStream {
|
||||||
|
let name = if input.is_empty() {
|
||||||
|
"time_end"
|
||||||
|
} else {
|
||||||
|
"time_end_with_label"
|
||||||
|
};
|
||||||
|
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::fixed(name, 1),
|
||||||
|
iter::once(ArgMode::PassThrough),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.timeLog()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/timeLog)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_time_log(input: TokenStream) -> TokenStream {
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::variadic("time_log_with_label_and_data", 1),
|
||||||
|
iter::once(ArgMode::PassThrough).chain(iter::repeat(ArgMode::IntoJsValue)),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.timeStamp()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/timeStamp)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_time_stamp(input: TokenStream) -> TokenStream {
|
||||||
|
let name = if input.is_empty() {
|
||||||
|
"time_stamp"
|
||||||
|
} else {
|
||||||
|
"time_stamp_with_data"
|
||||||
|
};
|
||||||
|
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::fixed(name, 1),
|
||||||
|
iter::once(ArgMode::IntoJsValue),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.trace()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/trace)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_trace(input: TokenStream) -> TokenStream {
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::variadic("trace", 0),
|
||||||
|
iter::repeat(ArgMode::IntoJsValue),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call the browser's `console.warn()` function.
|
||||||
|
/// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Console/warn)
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn console_warn(input: TokenStream) -> TokenStream {
|
||||||
|
quote_console_func(
|
||||||
|
ConsoleFunc::variadic("warn", 0),
|
||||||
|
iter::repeat(ArgMode::IntoJsValue),
|
||||||
|
input,
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use proc_macro2::{Ident, Span, TokenStream as TokenStream2};
|
||||||
|
use quote::quote;
|
||||||
|
use std::cmp;
|
||||||
|
use syn::parse::{Parse, ParseStream};
|
||||||
|
use syn::punctuated::Punctuated;
|
||||||
|
use syn::{parse_macro_input, Expr, Result, Token};
|
||||||
|
|
||||||
|
// quote_console_func builds and quotes a call to the browser's console API, based on the
|
||||||
|
// provided console function and argument types and the input token stream provider by
|
||||||
|
// the macro caller.
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
//
|
||||||
|
// * `func`: an object containing the target function name and parameter configuration.
|
||||||
|
// * `arg_modes`: an Iterator that will be called once per argument parsed from the input tokens.
|
||||||
|
// * `input`: the raw input tokens, as provided by the macro caller.
|
||||||
|
pub fn quote_console_func(
|
||||||
|
ConsoleFunc {
|
||||||
|
name,
|
||||||
|
params_fixed,
|
||||||
|
is_variadic,
|
||||||
|
}: ConsoleFunc,
|
||||||
|
mut arg_modes: impl Iterator<Item = ArgMode>,
|
||||||
|
input: TokenStream,
|
||||||
|
) -> TokenStream {
|
||||||
|
let InArgs(in_args) = parse_macro_input!(input as InArgs);
|
||||||
|
let mut out_args = in_args
|
||||||
|
.iter()
|
||||||
|
.map(|arg| quote_arg(arg, arg_modes.next().unwrap_or_default()));
|
||||||
|
|
||||||
|
let num_provided = out_args.len();
|
||||||
|
let num_fixed = cmp::min(num_provided, params_fixed);
|
||||||
|
let num_variadic = cmp::max(num_provided - num_fixed, 0);
|
||||||
|
|
||||||
|
let ident = {
|
||||||
|
let func_name = if is_variadic && num_variadic <= 7 {
|
||||||
|
format!("{}_{}", name, num_variadic)
|
||||||
|
} else {
|
||||||
|
name
|
||||||
|
};
|
||||||
|
Ident::new(&func_name, Span::call_site())
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut args: Punctuated<_, Token![,]> = Punctuated::new();
|
||||||
|
{
|
||||||
|
for _ in 0..num_fixed {
|
||||||
|
args.push(out_args.next().unwrap());
|
||||||
|
}
|
||||||
|
if num_variadic > 7 {
|
||||||
|
let variadic_args = out_args.collect::<Punctuated<_, Token![,]>>();
|
||||||
|
let ary = quote! {
|
||||||
|
&::std::iter::FromIterator::from_iter(::std::iter::IntoIterator::into_iter(::std::vec![#variadic_args]))
|
||||||
|
};
|
||||||
|
args.push(ary);
|
||||||
|
} else {
|
||||||
|
for _ in 0..num_variadic {
|
||||||
|
args.push(out_args.next().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(quote! { ::weblog::web_sys::console::#ident(#args) }).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn quote_arg(arg: &Expr, arg_mode: ArgMode) -> TokenStream2 {
|
||||||
|
match arg_mode {
|
||||||
|
ArgMode::PassThrough => {
|
||||||
|
quote! { #arg }
|
||||||
|
}
|
||||||
|
ArgMode::IntoJsValue => {
|
||||||
|
quote! { &::std::convert::Into::<::wasm_bindgen::JsValue>::into(#arg) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConsoleFunc represents the console API function being targeted.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ConsoleFunc {
|
||||||
|
name: String,
|
||||||
|
params_fixed: usize,
|
||||||
|
is_variadic: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConsoleFunc {
|
||||||
|
pub fn fixed(name: &str, params_fixed: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.into(),
|
||||||
|
params_fixed,
|
||||||
|
is_variadic: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn variadic(name: &str, params_fixed: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.into(),
|
||||||
|
params_fixed,
|
||||||
|
is_variadic: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArgMode represents an argument being passed to a targeted ConsoleFunc.
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub enum ArgMode {
|
||||||
|
PassThrough,
|
||||||
|
IntoJsValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ArgMode {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::PassThrough
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// InArgs is a struct required during parsing of input arguments.
|
||||||
|
struct InArgs(Punctuated<Expr, Token![,]>);
|
||||||
|
|
||||||
|
impl Parse for InArgs {
|
||||||
|
fn parse(input: ParseStream) -> Result<Self> {
|
||||||
|
let in_args: Punctuated<Expr, Token![,]> = Punctuated::parse_terminated(&input)?;
|
||||||
|
Ok(Self(in_args))
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue