# Assemble.app Rust Bindings
Bindings to deploy apps to Rust.
Currently implemnted:
* Database KV
* PubSub
## Building a View
Views should return an HTML string from the `render` method. This string can be constructed however you want, below we use the lightweight templating language, maude.
Events are dispatched by labeling elements with `assemble-` attributes. For example `` Will call the `event` method of your `ViewHandler` and then the `render` method. `message` will be called whenever we recieve a message on the pubsub topic that we subscribe to on our `start` method. The `start` method gets called once when the page load and sets the initial state.
It is important that your `render` method finishes as fast as possible without making any extra calls. All platform functions are disabled during this method.
## Example Usage:
```
#[macro_use]
extern crate assemble_app;
#[macro_use]
extern crate serde;
#[macro_use]
extern crate maud;
use assemble_app::*;
use maud::html;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
assemble_init! {{
register_view!(first_view, ViewHandler);
register_call!(first_call, some_call);
}}
#[derive(Deserialize, Serialize)]
struct Input {
inp: String,
}
#[derive(Deserialize, Serialize)]
struct Output {
out: u32,
}
#[derive(Deserialize, Serialize)]
struct ViewHandler {
clicks: u32,
other_clicks: u32,
}
impl View for ViewHandler {
fn start(_params: HashMap) -> Result {
pubsub_subscribe("clicks")?;
Ok(ViewHandler { other_clicks: 0, clicks: 0 })
}
fn render(&self) -> Result {
let markup = html! {
div class="bg-indigo-700" {
div class="max-w-2xl mx-auto text-center py-16 px-4 sm:py-20 sm:px-6 lg:px-8" {
h2 class="text-3xl font-extrabold text-white sm:text-4xl" {
span class="block" {
"This page was completely written in rust"
}
}
p class="mt-4 text-lg leading-6 text-indigo-200" {
"Interact with other tabs by clicking the button below. View the source here: " a href="https://gist.github.com/hansonkd/237de86ab12eed770ebf9c2984bfaa8f" {
github
}
}
p class="mt-4 text-lg leading-6 text-indigo-200" {
"Number of clicks from this tab: " (self.clicks)
}
p class="mt-4 text-lg leading-6 text-indigo-200" {
"Number of clicks from other tabs and users: " (self.other_clicks)
}
button assemble-click="i-was-clicked" class="mt-8 w-full inline-flex items-center justify-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-indigo-600 bg-white hover:bg-indigo-50 sm:w-auto" {
"Click me"
}
}
}
};
Ok(markup.into_string())
}
fn event(&mut self, msg: &str, payload: &[u8]) -> Result<()> {
// These are clicks from the current user
pubsub_publish_from("clicks", "click", "")?;
self.clicks += 1;
Ok(())
}
fn message(&mut self, topic: &str, event: &str, payload: &[u8]) -> Result<()> {
// These are clicks from other users
self.other_clicks += 1;
Ok(())
}
}
fn some_call(t: &Option) -> Result> {
let output = Output {
out: 42,
};
Ok(Box::new(output))
}
```