Skip to content

[Enhancement] log! output to respect \n byte, (and other \ escapes) #506

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Ben-PH opened this issue Jul 20, 2020 · 4 comments
Closed

[Enhancement] log! output to respect \n byte, (and other \ escapes) #506

Ben-PH opened this issue Jul 20, 2020 · 4 comments

Comments

@Ben-PH
Copy link
Contributor

Ben-PH commented Jul 20, 2020

When logging a pretty debug, instead of multi-line, you get something more like this:

"Outer {\n    inner: Inner0 {\n        inner: Inner1 {\n            field_name0: \"value\",\n            field_name1: \"value\",\n            field_name2: MyType,\n        },\n    },\n}"

Ideally, it would be as you'd get from the console:

"Outer {
    inner: Inner0 {
        inner: Inner1 {
            field_name0: "value",
            field_name1: "value",
            field_name2: MyType
        }
    }
}"

I'm no good with macros, so I wouldn't know where to start. I would happily work to assist directly, though. It would be nice to learn by working with someone on this.

@MartinKavik
Copy link
Member

I don't know how to replicate your problem, please elaborate a bit.

I tried:

#[derive(Debug, Default)]
struct Outer(Inner);

#[derive(Debug, Default)]
struct Inner {
    field_a: i32,
    field_b: i32,
}

fn init(_: Url, _: &mut impl Orders<Msg>) -> Model {
    log!(Outer::default());
    ...
}

and the result looks as expected:
image

@Ben-PH
Copy link
Contributor Author

Ben-PH commented Jul 21, 2020

Worked it out. I was using the format! macro out of habit.

Learning this, there's three options that come to mind: Leave it as is, change log! so that it removes the format! macro, or make a log_fmt! macro that does that.

I'd probably go for the first one, and add to the documentation that log! usage should be with comma separation rather than a format string.

If it's possible, maybe post format! expansion can map \n to the JS equivilant character when used inside log!? Even so, I suspect that wouldn't be the best way to interface with JS internals.

@MartinKavik
Copy link
Member

I don't want to change/design better API for logging until ideally these two issues are resolved:

  1. Redirect println! (and dbg!) to console.log - Proposal: Redirect println! to console.log #292
  2. seed/Cargo.toml

    Lines 37 to 39 in 8d04fcd

    # @TODO: remove once we can use entities without `Debug` in `log!` and `error!` on `stable` Rust.
    # https://github.com/Centril/rfcs/blob/rfc/quick-debug-macro/text/0000-quick-debug-macro.md#types-which-are-not-debug
    dbg = "1.0.4"

Another problem - do we want to use console.log? or .info or .debug or something else? Probably we should write/use a web_sys::console wrapper or/and a new Seed logger.

So there are some current Rust limitations and we can easily fall into the rabbit hole of the console and logging abstractions.


Until then log! for debugging and error! for error logging should be enough. However I would be glad if you want to improve the docs in the code to explain how to use these macros:

seed/src/shortcuts.rs

Lines 483 to 532 in 8d04fcd

/// A convenience function for logging to the web browser's console. We use
/// a macro to supplement the log function to allow multiple inputs.
///
/// NOTE: `log!` also accepts entities which don't implement `Debug` on `nightly` Rust.
/// It's useful because you don't have to add `Debug` bound to many places - implementation for
/// logged entity is enough.
#[macro_export]
macro_rules! log {
{ $($expr:expr),* $(,)? } => {
{
let mut formatted_exprs = Vec::new();
$(
formatted_exprs.push(format!("{:#?}", $crate::shortcuts::wrap_debug(&$expr)));
)*
$crate::shortcuts::log_1(
&formatted_exprs
.as_slice()
.join(" ")
.into()
);
}
};
}
// wrapper for `log_1` because we don't want to "leak" `web_sys` dependency through macro
pub fn log_1(data_1: &JsValue) {
web_sys::console::log_1(data_1);
}
/// Similar to log!
#[macro_export]
macro_rules! error {
{ $($expr:expr),* $(,)? } => {
{
let mut formatted_exprs = Vec::new();
$(
formatted_exprs.push(format!("{:#?}", $crate::shortcuts::wrap_debug(&$expr)));
)*
$crate::shortcuts::error_1(
&formatted_exprs
.as_slice()
.join(" ")
.into()
);
}
};
}
// wrapper for `error_1` because we don't want to "leak" `web_sys` dependency through macro
pub fn error_1(data_1: &JsValue) {
web_sys::console::error_1(data_1);
}

@Ben-PH
Copy link
Contributor Author

Ben-PH commented Jul 22, 2020

I'm in agreement. Also, since coming across this, I've seen other little things crop up that makes it look like the specifications of how to display text are at odds between Rust and JS. Your rabbit-hole comment prompts me to think it might be something for a stand-alone project.

I'll close this issue, and re-open a new one for documentation, referring back to this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants