Skip to content

Commit

Permalink
docs: Add deep dive tutorial of src/utils.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
danwilhelm committed Jan 13, 2019
1 parent a847529 commit 67ce98f
Showing 1 changed file with 64 additions and 1 deletion.
65 changes: 64 additions & 1 deletion docs/src/tutorial/template-deep-dive/src-utils-rs.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,66 @@
# src/utils.rs

🚧 COMING SOON 🚧
The purpose of `utils.rs` is to define the `utils` module, which contains a single function `set_panic_hook`. This function becomes part of the `utils` module in `lib.rs`, as described in the last section.

If the `console_error_panic_hook` feature is not enabled, then `set_panic_hook` is defined to be an inlined empty function. So, there is no run-time performance or code-size penalty incurred by its use.

We will discuss:
1. [Defining `set_panic_hook`](#a1-defining-set_panic_hook)
2. [Why `console_error_panic_hook`?](#a2-why-console_error_panic_hook)


---

## 1. Defining `set_panic_hook`

```
use cfg_if::cfg_if;
```

As described in the `src/lib.rs` tutorial, this allows us to write `cfg_if!` instead of `cfg_if::cfg_if!`.

```
cfg_if! {
if #[cfg(feature = "console_error_panic_hook")] {
extern crate console_error_panic_hook;
pub use self::console_error_panic_hook::set_once as set_panic_hook;
} else {
#[inline]
pub fn set_panic_hook() {}
}
}
```

As described in the `src/lib.rs` tutorial, the macro `cfg_if!` evaluates the `if` statement during compile time. This is possible because it is testing whether `"console_error_panic_hook"` is defined in the `[features]` section of `Cargo.toml` (among other ways), which is available during compile time.

The entire macro block will either be replaced with the statements in the `if` block or with those in the `else` block. These two cases are now described in turn:

```
extern crate console_error_panic_hook;
pub use self::console_error_panic_hook::set_once as set_panic_hook;
```

Due to the `use` statement, the function `self::console_error_panic_hook::set_once` can now be accessed more conveniently as `set_panic_hook`. Due to `pub`, this function will be publicly accessible outside of the `utils` module as `utils::set_panic_hook`.

```
#[inline]
pub fn set_panic_hook() {}
```

An inline function replaces the function call with the contents of the function during compile time. Here, `set_panic_hook` is defined to be an empty inline function. This allows the use of `set_panic_hook` with no run-time or code-size performance penalty if the feature is not enabled.

## 2. Why `console_error_panic_hook`?

The crate `console_error_panic_hook` enhances error messages within the web browser. This allows you to easily debug WebAssembly code.

Let's compare error messages before and after enabling the feature:

**Before:** `"RuntimeError: Unreachable executed"`

**After:** `"panicked at 'index out of bounds: the len is 3 but the index is 4', libcore/slice/mod.rs:2046:10"`

The crate provides a panic hook for WebAssembly that logs panics to the developer console via the JavaScript `console.error` function.

To use this feature, call `utils::set_panic_hook()` when your code first runs. The function may be called multiple times if needed.

For more details, see the [`console_error_panic_hook` repository](https://github.com/rustwasm/console_error_panic_hook).

0 comments on commit 67ce98f

Please sign in to comment.