## A counter example For our intermediate example, we will use the classic `counter` example. We will start by creating a new rust library project called `counter`. ```sh cargo new --lib counter ``` Modiy the `Cargo.toml` to be a library of crate-type "cdylib", since we are compiling it for a web application. Then add `sauron` to our dependency. ```toml [package] name = "counter" version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] [dependencies] sauron = "0.50.0" ``` In this example we will show 3 buttons where can click to increment/decrement and reset the count. We will start by defining our model. Remove the contents of `src/lib.rs` put this code. ```rust use sauron::prelude::*; struct App { count: i32, } impl App { fn new() -> Self { App { count: 0 } } } ``` We also added a function `new` to create our initial state of `App` which starts with count `0`. Next, we define out set of actions that our application will have. We will implement this using an `enum` with name `Msg`. ```rust enum Msg { Increment, Decrement, Reset, } ``` Next, we implement the `Application` trait for our model `App`. This is a way to define how our app should be displayed on page with the `view` method. Additionally, this also let us define how the `App` modifies its model with the `update` method. We also specify `Msg` to the `Application` trait which tells what type of messages that will be passed from events in the `view`, which also corresponds to the type we send into the `update` method. Append this code to `src/lib.rs`. ```rust use sauron::*; impl Application for App { type MSG = Msg; fn view(&self) -> Node { node! {
} } fn update(&mut self, msg: Msg) -> Cmd { match msg { Msg::Increment => self.count += 1, Msg::Decrement => self.count -= 1, Msg::Reset => self.count = 0, } Cmd::none() } } ``` The `view` method creates a html node tree. Notice, that the return type is `Node` which means it creates a html node where any of its member html elements has an event listener that can emit a `Msg` messages to the program handler. When a user clicks on the `+` button, this will emit an `Msg::Increment` message. The `update` method accepts `Msg` as an argument and modify our model `App` depending on the variant of our `Msg`. For now, we return `Cmd::none()` at the end of the update method. `Cmd` is a way to tell the program to execute something, we will cover this in a more advanced example. Next, we define an entry point for our `wasm` web app. This is done by anotating a public function with `#[wasm_bindgen(start)]`. Append this code to `src/lib.rs`. ```rust #[wasm_bindgen(start)] pub fn start() { Program::mount_to_body(App::new()); } ``` Inside this function, we define how our app is to be mounted into our `index.html` page. In this case we mount it to the `body` of our html page. The [`Program`](https://docs.rs/sauron/latest/sauron/struct.Program.html) object provides other methods on how to mount your application into the document. Next, we need to link our application in a html page. Put this in `index.html` file at the project base folder. You can put your styles as usual. ```html Counter ``` Make sure that the filename of the javascript file (`./pkg/counter.js`) in the `import` file matches the package name of your web app (`counter`). Double check this part of the code especially if you change the package name of your web app. Compile the web app by issuing the command: ```shell wasm-pack build --release --target=web ``` You need to issue this command everytime you modify the rust code. Finally, serve the files using `basic-http-server` at port `4004` ```shell basic-http-server -a 0.0.0.0:4004 ``` Then navigate your browser http://localhost:4004 to see and interact with the app.