on master help sign in
Add READMEs and comments for examples
307c8d1Nick Fitzgerald
examples/counter/README.md+12โˆ’20
@@ -1,29 +1,21 @@
1โˆ’# ๐Ÿฆ€๐Ÿ•ธ `rust-webpack-template`
1+# Counter
2
2
3โˆ’> **Kickstart your Rust, WebAssembly, and Webpack project!**
3+A counter that can be incremented and decremented.
4
4
5โˆ’This template is designed for creating monorepo-style Web applications with
5+## Source
6โˆ’Rust-generated WebAssembly and Webpack without publishing your wasm to NPM.
7
6
8โˆ’* Want to create and publish NPM packages with Rust and WebAssembly? [Check out
7+See `src/lib.rs`.
9โˆ’ `wasm-pack-template`.](https://github.com/rustwasm/wasm-pack-template)
10
8
11โˆ’## ๐Ÿ”‹ Batteries Included
9+## Build
12
10
13โˆ’This template comes pre-configured with all the boilerplate for compiling Rust
11+```
14โˆ’to WebAssembly and hooking into a Webpack build pipeline.
12+wasm-pack build --target no-modules
15โˆ’
13+```
16โˆ’* `npm run start` -- Serve the project locally for development at
17โˆ’ `http://localhost:8080`.
18โˆ’
19โˆ’* `npm run build` -- Bundle the project (in production mode).
20โˆ’
21โˆ’## ๐Ÿšด Using This Template
22
14
23โˆ’First, [install `wasm-pack`!](https://rustwasm.github.io/wasm-pack/installer/)
15+## Serve
24
16
25โˆ’Then, use `npm init` to clone this template:
17+Use any HTTP server, for example:
26
18
27โˆ’```sh
19+```
28โˆ’npm init rust-webpack my-app
20+python -m SimpleHTTPServer
29```
21```
examples/counter/src/lib.rs+25โˆ’7
@@ -3,30 +3,37 @@ use dodrio::{on, Node, Render};
3use log::*;
3use log::*;
4use wasm_bindgen::prelude::*;
4use wasm_bindgen::prelude::*;
5
5
6+/// A counter that can be incremented and decrmented!
6struct Counter {
7struct Counter {
7โˆ’ val: isize,
8+ count: isize,
8}
9}
9
10
10impl Counter {
11impl Counter {
12+ /// Construct a new, zeroed counter.
11 fn new() -> Counter {
13 fn new() -> Counter {
12โˆ’ Counter { val: 0 }
14+ Counter { count: 0 }
13 }
15 }
14
16
17+ /// Increment this counter's count.
15 fn increment(&mut self) {
18 fn increment(&mut self) {
16โˆ’ self.val += 1;
19+ self.count += 1;
17 }
20 }
18
21
22+ /// Decrement this counter's count.
19 fn decrement(&mut self) {
23 fn decrement(&mut self) {
20โˆ’ self.val -= 1;
24+ self.count -= 1;
21 }
25 }
22}
26}
23
27
28+// The `Render` implementation for `Counter`s displays the current count and has
29+// buttons to increment and decrement the count.
24impl Render for Counter {
30impl Render for Counter {
25 fn render<'a, 'bump>(&'a self, bump: &'bump Bump) -> dodrio::Node<'bump>
31 fn render<'a, 'bump>(&'a self, bump: &'bump Bump) -> dodrio::Node<'bump>
26 where
32 where
27 'a: 'bump,
33 'a: 'bump,
28 {
34 {
35+ // Stringify the count as a bump-allocated string.
29โˆ’ let val = bumpalo::format!(in bump, "{}", self.val);
36+ let count = bumpalo::format!(in bump, "{}", self.count);
30
37
31 Node::element(
38 Node::element(
32 bump,
39 bump,
@@ -38,17 +45,26 @@ impl Render for Counter {
38 bump,
45 bump,
39 "button",
46 "button",
40 [on(bump, "click", |root, vdom, _event| {
47 [on(bump, "click", |root, vdom, _event| {
48+ // Cast the root render component to a `Counter`, since
49+ // we know that's what it is.
41โˆ’ root.unwrap_mut::<Counter>().increment();
50+ let counter = root.unwrap_mut::<Counter>();
51+
52+ // Increment the counter.
53+ counter.increment();
54+
55+ // Since the count has updated, we should re-render the
56+ // counter on the next animation frame.
42 vdom.schedule_render();
57 vdom.schedule_render();
43 })],
58 })],
44 [],
59 [],
45 [Node::text("+")],
60 [Node::text("+")],
46 ),
61 ),
47โˆ’ Node::text(val.into_bump_str()),
62+ Node::text(count.into_bump_str()),
48 Node::element(
63 Node::element(
49 bump,
64 bump,
50 "button",
65 "button",
51 [on(bump, "click", |root, vdom, _event| {
66 [on(bump, "click", |root, vdom, _event| {
67+ // Same as above, but decrementing instead of incrementing.
52 root.unwrap_mut::<Counter>().decrement();
68 root.unwrap_mut::<Counter>().decrement();
53 vdom.schedule_render();
69 vdom.schedule_render();
54 })],
70 })],
@@ -62,9 +78,11 @@ impl Render for Counter {
62
78
63#[wasm_bindgen(start)]
79#[wasm_bindgen(start)]
64pub fn run() {
80pub fn run() {
81+ // Initialize debug logging for if/when things go wrong.
65 console_error_panic_hook::set_once();
82 console_error_panic_hook::set_once();
66 console_log::init_with_level(Level::Trace).expect("should initialize logging OK");
83 console_log::init_with_level(Level::Trace).expect("should initialize logging OK");
67
84
85+ // Get the document's `<body>`.
68 let window = web_sys::window().unwrap();
86 let window = web_sys::window().unwrap();
69 let document = window.document().unwrap();
87 let document = window.document().unwrap();
70 let body = document.body().unwrap();
88 let body = document.body().unwrap();
examples/hello-world/README.md+12โˆ’20
@@ -1,29 +1,21 @@
1โˆ’# ๐Ÿฆ€๐Ÿ•ธ `rust-webpack-template`
1+# Hello World
2
2
3โˆ’> **Kickstart your Rust, WebAssembly, and Webpack project!**
3+The most basic example!
4
4
5โˆ’This template is designed for creating monorepo-style Web applications with
5+## Source
6โˆ’Rust-generated WebAssembly and Webpack without publishing your wasm to NPM.
7
6
8โˆ’* Want to create and publish NPM packages with Rust and WebAssembly? [Check out
7+See `src/lib.rs`.
9โˆ’ `wasm-pack-template`.](https://github.com/rustwasm/wasm-pack-template)
10
8
11โˆ’## ๐Ÿ”‹ Batteries Included
9+## Build
12
10
13โˆ’This template comes pre-configured with all the boilerplate for compiling Rust
11+```
14โˆ’to WebAssembly and hooking into a Webpack build pipeline.
12+wasm-pack build --target no-modules
15โˆ’
13+```
16โˆ’* `npm run start` -- Serve the project locally for development at
17โˆ’ `http://localhost:8080`.
18โˆ’
19โˆ’* `npm run build` -- Bundle the project (in production mode).
20โˆ’
21โˆ’## ๐Ÿšด Using This Template
22
14
23โˆ’First, [install `wasm-pack`!](https://rustwasm.github.io/wasm-pack/installer/)
15+## Serve
24
16
25โˆ’Then, use `npm init` to clone this template:
17+Use any HTTP server, for example:
26
18
27โˆ’```sh
19+```
28โˆ’npm init rust-webpack my-app
20+python -m SimpleHTTPServer
29```
21```
examples/hello-world/src/lib.rs+11โˆ’7
@@ -2,16 +2,14 @@ use dodrio::bumpalo::Bump;
2use dodrio::{Node, Render, Vdom};
2use dodrio::{Node, Render, Vdom};
3use wasm_bindgen::prelude::*;
3use wasm_bindgen::prelude::*;
4
4
5+/// A rendering component that displays a greeting.
5struct Hello<'who> {
6struct Hello<'who> {
7+ /// Who to greet.
6 who: &'who str,
8 who: &'who str,
7}
9}
8
10
9โˆ’impl<'who> Hello<'who> {
11+// The `Render` implementation describes how to render a `Hello` component into
10โˆ’ fn new(who: &str) -> Hello {
12+// HTML.
11โˆ’ Hello { who }
12โˆ’ }
13โˆ’}
14โˆ’
15impl<'who> Render for Hello<'who> {
13impl<'who> Render for Hello<'who> {
16 fn render<'a, 'bump>(&'a self, bump: &'bump Bump) -> Node<'bump>
14 fn render<'a, 'bump>(&'a self, bump: &'bump Bump) -> Node<'bump>
17 where
15 where
@@ -19,9 +17,13 @@ impl<'who> Render for Hello<'who> {
19 {
17 {
20 Node::element(
18 Node::element(
21 bump,
19 bump,
20+ // The element's tag name. In this case a `<p>` element.
22 "p",
21 "p",
22+ // Event listeners. Empty in this case.
23 [],
23 [],
24+ // Attributes. Again, empty in this case.
24 [],
25 [],
26+ // Child nodes.
25 [Node::text("Hello, "), Node::text(self.who), Node::text("!")],
27 [Node::text("Hello, "), Node::text(self.who), Node::text("!")],
26 )
28 )
27 }
29 }
@@ -29,14 +31,16 @@ impl<'who> Render for Hello<'who> {
29
31
30#[wasm_bindgen(start)]
32#[wasm_bindgen(start)]
31pub fn run() {
33pub fn run() {
34+ // Set up the panic hook for debugging when things go wrong.
32 console_error_panic_hook::set_once();
35 console_error_panic_hook::set_once();
33
36
37+ // Grab the document's `<body>`.
34 let window = web_sys::window().unwrap_throw();
38 let window = web_sys::window().unwrap_throw();
35 let document = window.document().unwrap_throw();
39 let document = window.document().unwrap_throw();
36 let body = document.body().unwrap_throw();
40 let body = document.body().unwrap_throw();
37
41
38 // Create a new `Hello` render component.
42 // Create a new `Hello` render component.
39โˆ’ let component = Hello::new("World");
43+ let component = Hello { who: "World" };
40
44
41 // Create a virtual DOM and mount it and the `Hello` render component to the
45 // Create a virtual DOM and mount it and the `Hello` render component to the
42 // `<body>`.
46 // `<body>`.
examples/input-form/README.md+13โˆ’20
@@ -1,29 +1,22 @@
1โˆ’# ๐Ÿฆ€๐Ÿ•ธ `rust-webpack-template`
1+# Input Forms
2
2
3โˆ’> **Kickstart your Rust, WebAssembly, and Webpack project!**
3+Renders a greeting to a user-supplied person via an `<input>` value. The
4+greeting is live-updated with new inputs.
4
5
5โˆ’This template is designed for creating monorepo-style Web applications with
6+## Source
6โˆ’Rust-generated WebAssembly and Webpack without publishing your wasm to NPM.
7
7
8โˆ’* Want to create and publish NPM packages with Rust and WebAssembly? [Check out
8+See `src/lib.rs`.
9โˆ’ `wasm-pack-template`.](https://github.com/rustwasm/wasm-pack-template)
10
9
11โˆ’## ๐Ÿ”‹ Batteries Included
10+## Build
12
11
13โˆ’This template comes pre-configured with all the boilerplate for compiling Rust
12+```
14โˆ’to WebAssembly and hooking into a Webpack build pipeline.
13+wasm-pack build --target no-modules
15โˆ’
14+```
16โˆ’* `npm run start` -- Serve the project locally for development at
17โˆ’ `http://localhost:8080`.
18โˆ’
19โˆ’* `npm run build` -- Bundle the project (in production mode).
20โˆ’
21โˆ’## ๐Ÿšด Using This Template
22
15
23โˆ’First, [install `wasm-pack`!](https://rustwasm.github.io/wasm-pack/installer/)
16+## Serve
24
17
25โˆ’Then, use `npm init` to clone this template:
18+Use any HTTP server, for example:
26
19
27โˆ’```sh
20+```
28โˆ’npm init rust-webpack my-app
21+python -m SimpleHTTPServer
29```
22```
examples/input-form/src/lib.rs+17โˆ’2
@@ -3,21 +3,27 @@ use dodrio::{on, Attribute, Node, Render};
3use wasm_bindgen::prelude::*;
3use wasm_bindgen::prelude::*;
4use wasm_bindgen::JsCast;
4use wasm_bindgen::JsCast;
5
5
6+/// Say hello to someone.
6struct SayHelloTo {
7struct SayHelloTo {
8+ /// Who to say hello to.
7 who: String,
9 who: String,
8}
10}
9
11
10impl SayHelloTo {
12impl SayHelloTo {
13+ /// Construct a new `SayHelloTo` component.
11 fn new<S: Into<String>>(who: S) -> SayHelloTo {
14 fn new<S: Into<String>>(who: S) -> SayHelloTo {
12 let who = who.into();
15 let who = who.into();
13 SayHelloTo { who }
16 SayHelloTo { who }
14 }
17 }
15
18
19+ /// Update who to say hello to.
16 fn set_who(&mut self, who: String) {
20 fn set_who(&mut self, who: String) {
17 self.who = who;
21 self.who = who;
18 }
22 }
19}
23}
20
24
25+// The `Render` implementation has a text `<input>` and a `<div>` that shows a
26+// greeting to the `<input>`'s value.
21impl Render for SayHelloTo {
27impl Render for SayHelloTo {
22 fn render<'a, 'bump>(&'a self, bump: &'bump Bump) -> dodrio::Node<'bump>
28 fn render<'a, 'bump>(&'a self, bump: &'bump Bump) -> dodrio::Node<'bump>
23 where
29 where
@@ -27,15 +33,21 @@ impl Render for SayHelloTo {
27 bump,
33 bump,
28 "input",
34 "input",
29 [on(bump, "input", |root, vdom, event| {
35 [on(bump, "input", |root, vdom, event| {
36+ // If the event's target is our input...
30 let input = match event
37 let input = match event
31 .target()
38 .target()
32 .and_then(|t| t.dyn_into::<web_sys::HtmlInputElement>().ok())
39 .and_then(|t| t.dyn_into::<web_sys::HtmlInputElement>().ok())
33 {
40 {
34โˆ’ Some(input) => input,
35 None => return,
41 None => return,
42+ Some(input) => input,
36 };
43 };
37
44
45+ // ...then get its value and update who we are greeting.
46+ let value = input.value();
38โˆ’ root.unwrap_mut::<SayHelloTo>().set_who(input.value());
47+ let hello = root.unwrap_mut::<SayHelloTo>();
48+ hello.set_who(value);
49+
50+ // Finally, re-render the component on the next animation frame.
39 vdom.schedule_render();
51 vdom.schedule_render();
40 })],
52 })],
41 [
53 [
@@ -60,12 +72,15 @@ impl Render for SayHelloTo {
60
72
61#[wasm_bindgen(start)]
73#[wasm_bindgen(start)]
62pub fn run() {
74pub fn run() {
75+ // Initialize debugging for when/if something goes wrong.
63 console_error_panic_hook::set_once();
76 console_error_panic_hook::set_once();
64
77
78+ // Get the document's `<body>`.
65 let window = web_sys::window().unwrap();
79 let window = web_sys::window().unwrap();
66 let document = window.document().unwrap();
80 let document = window.document().unwrap();
67 let body = document.body().unwrap();
81 let body = document.body().unwrap();
68
82
83+ // Construct a new `SayHelloTo` rendering component.
69 let say_hello = SayHelloTo::new("World");
84 let say_hello = SayHelloTo::new("World");
70
85
71 // Mount the component to the `<body>`.
86 // Mount the component to the `<body>`.