# Buttons Our first example is a counter that can be incremented or decremented. I included the full program below. Put this into `src/lib.rs`. ```rust use sauron::prelude::*; #[derive(Debug)] pub enum Msg { Increment, Decrement, } pub struct App { count: i32, } impl App { pub fn new() -> Self { App { count: 0 } } } impl Application for App { fn view(&self) -> Node { node! {
{text(self.count)}
} } fn update(&mut self, msg: Msg) -> Cmd { match msg { Msg::Increment => self.count += 1, Msg::Decrement => self.count -= 1, } Cmd::none() } } #[wasm_bindgen(start)] pub fn main() { Program::mount_to_body(App::new()); } ``` Put this into your `Cargo.toml`. ```toml [package] name = "counter" version = "0.1.0" authors = ["Jovansonlee Cesar "] edition = "2018" [lib] crate-type = ["cdylib"] [dependencies] sauron = "0.43" ``` Put this into you `index.html`. ```html Counter ``` Compile the project using: ``` wasm-pack build --release --target=web ``` This will produce files in `pkg` directory, with names derived from the crate name. In this case `pkg/counter.js` and `pkg/counter_bg.wasm`. ## Main The `main` function here is the entry point of our application. The function doesn't have to be named `main` as long as it is anotated with `#[(wasm_bindgen(start)]`. It tells the the runtime on where to display the application. In this case, we are going to initialize our application by calling it's `fn new()->Self` method. The `view` function is going to show everything on screen, and user input is going to be fed into the `update` function. Think of this as the high-level description of our program. ```rust #[wasm_bindgen(start)] pub fn main() { Program::mount_to_body(App::new()); } ``` ## Model Data modeling is extremely important in Elm. The point of the mode is to capture all the details about your application as data. To make a counter, we need to keep track of a number that is going up and down. That means our model is really small this time: ```rust pub struct App { count: i32, } ``` We just need an `i32` value to track the current count. We can see that in out initial value: ```rust impl App { pub fn new() -> Self { App { count: 0 } } } ``` The initial value is zero, and it will go up and down as people press different buttons. ## View We have a model, but how do we show it on screen? The is the role of the `view` function: ```rust impl Application for App { fn view(&self) -> Node { node! {
{text(self.count)}
} } } ``` This function takes in the `App` as an argument. It outputs HTML. So we are saying that we want to show a decrement button, the current count, and an increment button. Notice that we have an `on_click` handler for each button. These are saying: *when someone clicks, generate a message*. So the plus button is generating an `Increment` message. What is that and where does it go? To the `update` function! ## Update The `update` function describes how our `Model` will change over time. We defined 2 messages that it might receive: ```rust #[derive(Debug)] pub enum Msg { Increment, Decrement, } ``` From there, the `update` function just describes what to do when you receive one of these messages. ```rust impl Application for App { fn update(&mut self, msg: Msg) -> Cmd { match msg { Msg::Increment => self.count += 1, Msg::Decrement => self.count -= 1, } Cmd::none() } } ``` If you get an `Increment` message, you increment the model. If you get a `Decrement` message, you decrement the model. So whenever we get a message, we run it through `update` to get a new model. We then call the `view` to figure out how to show the new model on screen. Then repeat! User input generates a message, `update` the model, `view` it on screen. Etc. ## Overview Now that you have seen all the parts of a Sauron program, it may be a bit easier to see how they fit into the diagram we saw earlier: ```bob +-------+ | Model | <--- update ----. +-------+ | | | | .---. view ( Msg ) | `---' V | +-------+ | | Html | ---- events ----' +-------+ ``` Sauron starts by rendering the initial value on screen. From there you enter into this loop: 1. Wait for user input. 2. Send a message to `update` 3. Produce a new `Model` 4. Call `view` to get a new HTML 5. Show the new HTML on screen. 6. Repeat. This is the essence of Sauron archicture. Every example we see from now on will be a slight variation on this basic pattern. Exercise: Add a button to reset the counter to zero: 1. Add a `Reset` variant to the `Msg` type. 2. Add a `Reset` branch in the `update` function 3. Add a button in the `view` function.