From d7d7737c42bfdebe408b3431a0cb8b7700e9adce Mon Sep 17 00:00:00 2001 From: Rob Watson Date: Thu, 26 Nov 2020 09:20:49 +0100 Subject: [PATCH] WIP: traits --- examples/web-sys/src/lib.rs | 12 +++-- src/console/web_sys.rs | 67 ++++++++++++++++++++++++++++ src/lib.rs | 8 ++-- weblog-proc-macro/src/lib.rs | 26 +++++------ weblog-proc-macro/src/weblog_impl.rs | 11 ++--- 5 files changed, 100 insertions(+), 24 deletions(-) diff --git a/examples/web-sys/src/lib.rs b/examples/web-sys/src/lib.rs index 06dfc76..68e9323 100644 --- a/examples/web-sys/src/lib.rs +++ b/examples/web-sys/src/lib.rs @@ -10,14 +10,20 @@ pub fn main() { console_log!("Hello", "there", "world"); // Various types. + console_log!("f32", 1f32, "f64", 2f64); + console_log!("u8", 3u8, "i8", 4i8); + console_log!("u16", 5u16, "i16", 6i16); + console_log!("u32", 7u32, "i32", 8i8); + //console_log!("u64", 9u64, "i64", 10i64); + console_log!("usize", 11usize, "isize", 12isize); + + // More types. console_log!( - 1.0, - 2f64, true, "&str", String::from("owned string"), Some("an option"), - None as Option, + (None as Option), ); // Various levels. diff --git a/src/console/web_sys.rs b/src/console/web_sys.rs index 0ce70db..2108093 100644 --- a/src/console/web_sys.rs +++ b/src/console/web_sys.rs @@ -3,6 +3,73 @@ pub use ::wasm_bindgen; #[doc(hidden)] pub use ::web_sys; +use ::wasm_bindgen::JsValue; + +pub struct ConsoleArg(JsValue); + +impl ConsoleArg { + pub fn into_inner(self) -> JsValue { + self.0 + } +} + +use crate::ToConsole; + +macro_rules! into_jsvalue { + ($($n:ident),*) => ($( + impl ToConsole for $n { + #[inline] + fn to_console(self) -> ConsoleArg { + ConsoleArg(self.into()) + } + } + )*) +} + +// TODO u64 and f64? +// TODO: impl<'a, T> From<&'a T> for JsValue where T: JsCast ? + +into_jsvalue!(bool, f32, f64, i8, i16, i32, u8, u16, u32, String); + +impl<'a> ToConsole for &'a String { + fn to_console(self) -> ConsoleArg { + ConsoleArg(self.into()) + } +} + +impl<'a> ToConsole for &'a str { + fn to_console(self) -> ConsoleArg { + ConsoleArg(self.into()) + } +} + +impl ToConsole for Option +where + T: ToConsole, +{ + fn to_console(self) -> ConsoleArg { + match self { + Some(s) => s.to_console(), + None => ConsoleArg(JsValue::undefined()), + } + } +} + +impl ToConsole for usize { + fn to_console(self) -> ConsoleArg { + // usize/isize is always 32-bit in Wasm. + // But perhaps this should have a guard of some kind. + ConsoleArg((self as u32).into()) + } +} + +impl ToConsole for isize { + fn to_console(self) -> ConsoleArg { + // As above. + ConsoleArg((self as i32).into()) + } +} + // It is necessary to expose these wrapper macros in order to pass the $crate // meta-variable to the proc macro. This in turn allows the macros to be // re-exported from third-party crates without breakage. diff --git a/src/lib.rs b/src/lib.rs index bd53771..41b0b90 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,12 +74,14 @@ //! ```toml //! weblog = { version = "0.3", default-features = false, features = ["stdweb"] } //! ``` -//! mod console; -#[cfg(feature = "web_sys")] -pub use self::console::web_sys::*; +pub trait ToConsole { + fn to_console(self) -> ConsoleArg; +} #[cfg(feature = "std_web")] pub use self::console::std_web::*; +#[cfg(feature = "web_sys")] +pub use self::console::web_sys::*; diff --git a/weblog-proc-macro/src/lib.rs b/weblog-proc-macro/src/lib.rs index c701011..60f72e7 100644 --- a/weblog-proc-macro/src/lib.rs +++ b/weblog-proc-macro/src/lib.rs @@ -16,7 +16,7 @@ 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)), + iter::once(ArgMode::PassThrough).chain(iter::repeat(ArgMode::Console)), crate_name, args, ) @@ -80,7 +80,7 @@ pub fn console_debug(input: TokenStream) -> TokenStream { quote_console_func( ConsoleFunc::variadic("debug", 0), - iter::repeat(ArgMode::IntoJsValue), + iter::repeat(ArgMode::Console), crate_name, args, ) @@ -93,7 +93,7 @@ pub fn console_dir(input: TokenStream) -> TokenStream { quote_console_func( ConsoleFunc::variadic("dir", 0), - iter::repeat(ArgMode::IntoJsValue), + iter::repeat(ArgMode::Console), crate_name, args, ) @@ -106,7 +106,7 @@ pub fn console_dirxml(input: TokenStream) -> TokenStream { quote_console_func( ConsoleFunc::variadic("dirxml", 0), - iter::repeat(ArgMode::IntoJsValue), + iter::repeat(ArgMode::Console), crate_name, args, ) @@ -119,7 +119,7 @@ pub fn console_error(input: TokenStream) -> TokenStream { quote_console_func( ConsoleFunc::variadic("error", 0), - iter::repeat(ArgMode::IntoJsValue), + iter::repeat(ArgMode::Console), crate_name, args, ) @@ -132,7 +132,7 @@ pub fn console_exception(input: TokenStream) -> TokenStream { quote_console_func( ConsoleFunc::variadic("exception", 0), - iter::repeat(ArgMode::IntoJsValue), + iter::repeat(ArgMode::Console), crate_name, args, ) @@ -145,7 +145,7 @@ pub fn console_info(input: TokenStream) -> TokenStream { quote_console_func( ConsoleFunc::variadic("info", 0), - iter::repeat(ArgMode::IntoJsValue), + iter::repeat(ArgMode::Console), crate_name, args, ) @@ -158,7 +158,7 @@ pub fn console_log(input: TokenStream) -> TokenStream { quote_console_func( ConsoleFunc::variadic("log", 0), - iter::repeat(ArgMode::IntoJsValue), + iter::repeat(ArgMode::Console), crate_name, args, ) @@ -171,7 +171,7 @@ pub fn console_table(input: TokenStream) -> TokenStream { quote_console_func( ConsoleFunc::variadic("table", 0), - iter::repeat(ArgMode::IntoJsValue), + iter::repeat(ArgMode::Console), crate_name, args, ) @@ -222,7 +222,7 @@ 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)), + iter::once(ArgMode::PassThrough).chain(iter::repeat(ArgMode::Console)), crate_name, args, ) @@ -241,7 +241,7 @@ pub fn console_time_stamp(input: TokenStream) -> TokenStream { quote_console_func( ConsoleFunc::fixed(name, 1), - iter::once(ArgMode::IntoJsValue), + iter::once(ArgMode::Console), crate_name, args, ) @@ -254,7 +254,7 @@ pub fn console_trace(input: TokenStream) -> TokenStream { quote_console_func( ConsoleFunc::variadic("trace", 0), - iter::repeat(ArgMode::IntoJsValue), + iter::repeat(ArgMode::Console), crate_name, args, ) @@ -267,7 +267,7 @@ pub fn console_warn(input: TokenStream) -> TokenStream { quote_console_func( ConsoleFunc::variadic("warn", 0), - iter::repeat(ArgMode::IntoJsValue), + iter::repeat(ArgMode::Console), crate_name, args, ) diff --git a/weblog-proc-macro/src/weblog_impl.rs b/weblog-proc-macro/src/weblog_impl.rs index cbec3a3..8388e64 100644 --- a/weblog-proc-macro/src/weblog_impl.rs +++ b/weblog-proc-macro/src/weblog_impl.rs @@ -32,7 +32,7 @@ pub fn quote_console_func( ) -> TokenStream { let mut out_args = in_args .iter() - .map(|arg| quote_arg(&crate_name, arg, arg_modes.next().unwrap_or_default())); + .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); @@ -68,14 +68,15 @@ pub fn quote_console_func( (quote! { #crate_name::web_sys::console::#ident(#args) }).into() } -fn quote_arg(crate_name: &Ident, arg: &Expr, arg_mode: ArgMode) -> TokenStream2 { +#[inline] +fn quote_arg(arg: &Expr, arg_mode: ArgMode) -> TokenStream2 { match arg_mode { ArgMode::PassThrough => { quote! { #arg } } - ArgMode::IntoJsValue => { + ArgMode::Console => { quote! { - &::std::convert::Into::<#crate_name::wasm_bindgen::JsValue>::into(#arg) + &#arg.to_console().into_inner() } } } @@ -111,7 +112,7 @@ impl ConsoleFunc { #[derive(Debug, Copy, Clone)] pub enum ArgMode { PassThrough, - IntoJsValue, + Console, } impl Default for ArgMode {