#assemble #serialization #deserialize #kv #html #view #bootstrap

assemble_app

https://assemble.app 的 Bootstrap 库

37 个版本

0.1.36 2020年12月28日
0.1.35 2020年12月28日

#1264编码

Apache-2.0

17KB
361

Assemble.app Rust 绑定

用于将应用程序部署到 Rust 的绑定。

当前实现

  • 数据库 KV
  • 发布/订阅

构建视图

视图应该从 render 方法返回一个 HTML 字符串。这个字符串可以按照您的方式构造,以下我们使用轻量级模板语言 maude。

通过为元素添加 assemble- 属性来分发事件。例如,<button assemble-click="i-was-clicked">Button</button> 将调用您的 ViewHandlerevent 方法,然后调用 render 方法。每当我们在 start 方法中订阅的 pubsub 主题接收到消息时,都会调用 message。当页面加载时,会调用一次 start 方法并设置初始状态。

您的 render 方法应尽可能快地完成,而不进行任何额外的调用。在此方法期间,所有平台功能都被禁用。

示例用法

#[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<String, String>) -> Result<Self> {
    pubsub_subscribe("clicks")?;
    Ok(ViewHandler { other_clicks: 0, clicks: 0 })
  }

  fn render(&self) -> Result<Html> {
    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<Input>) -> Result<Box<Output>> {
    let output = Output {
        out: 42,
    };
    Ok(Box::new(output))
}

依赖项

~1.7–2.5MB
~48K SLoC