Am testat doua biblioteci de aplicatii-web in Rust: shio si actix-web.
Se pare ca imi place shio mai mult si am schitat o mica aplicatie cu interfata web:
extern crate shio;
extern crate askama;
use askama::Template;
use hyper::mime;
use shio::prelude::*;
use std::env;
// https://lib.rs/crates/rust-embed
// e foarte tare: comprima fisierele si le stocheaza in executabil
use rust_embed::RustEmbed;
#[derive(RustEmbed)]
#[folder = "static/"]
#[prefix = "/static/"]
struct Asset;
#[derive(Template)]
#[template(path = "index.tpl")]
struct IndexTemplate {
title: String,
cnt: i64,
mylist: [i32; 5],
mylist2: [String; 3],
}
#[derive(Template)]
#[template(path = "info.tpl")]
struct InfoTemplate {
title: String,
msg: String,
}
static mut CNT: i64 = 0;
fn index(_: Context) -> Result {
unsafe {
Response::with(IndexTemplate {
title: String::from("The index"),
cnt: CNT,
mylist: [1, 11, 2, 333, 88],
mylist2: [
String::from("A111"),
String::from("B2"),
String::from("C300"),
],
})
}
}
fn inc_cnt(_: Context) -> Result {
unsafe {
CNT = CNT + 1;
Response::with(InfoTemplate {
title: String::from("Inc cnt"),
msg: format!("cnt={}", CNT),
})
}
}
fn set_cnt(_: Context) -> Result {
unsafe {
CNT = 0;
Response::with(InfoTemplate {
title: String::from("Reset cnt"),
msg: format!("cnt={}", CNT),
})
}
}
fn static_embedded(ctx: Context) -> Response {
let filename = ctx.path();
let static_type: hyper::mime::Mime = match filename {
x if x.ends_with(".css") => mime::TEXT_CSS,
x if x.ends_with(".js") => mime::APPLICATION_JAVASCRIPT,
x if x.ends_with(".woff") => mime::FONT_WOFF,
x if x.ends_with(".woff2") => mime::FONT_WOFF2,
_ => mime::TEXT_PLAIN,
};
println!("static type={} path={}", static_type, filename);
let ret = Asset::get(ctx.path()).unwrap();
unsafe {
let text = String::from(std::str::from_utf8_unchecked(ret.as_ref()));
Response::build()
.status(StatusCode::Ok)
.header(header::ContentType(static_type))
.body(text)
}
}
const DEFAULT_HOST: &str = "127.0.0.1:80";
fn main() {
// are 5 mega exe final
// e un pic mai rapid decat actix
for file in Asset::iter() {
println!("{}", file.as_ref());
}
let host = env::args()
.nth(1)
.unwrap_or_else(|| DEFAULT_HOST.to_string());
println!("Start shio webserver on {}", host);
let mut router = shio::router::Router::new();
router.add((Method::Get, "/", index));
router.add((Method::Get, "/inc", inc_cnt));
router.add((Method::Get, "/set", set_cnt));
// routerul accepta regex in calea rutei
router.add((Method::Get, "/static/[\\w\\W/]+", static_embedded));
let service = Shio::new(router);
service.run(host).unwrap();
}
Fisierul Cargo.toml:
[package]
name = "teste-web-embed"
version = "0.1.0"
authors = ["Ioan Coman"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rust-embed="5.9.0"
shio = "0.2.0"
askama = { git = "https://github.com/mehcode/askama", features = ["with-shio"] }
hyper = "0.11.2"
In folderul proiectului se afla folderul static cu cateva fisiere css, js si bootstrap3, in total 3.10 MB si folderul templates cu index.tpl, header.tpl si info.tpl.
Fisierul index.tpl din folderul templates:
{% include "header.tpl" %}
<h1>{{ title }}</h1>
<hr>
<a href="/a1">/a1</a> -
<a href="/inc">/inc cnt</a> -
<a href="/set">/set cnt=0</a>
<br><br>
cnt = {{ cnt }} -
{% if (cnt > 10) %}
este > 10
{% else %}
nu este > 10
{% endif %}
<br>
<ol>
{% for s in mylist %}
<li>{{- loop.index0 }} --- {{ s }}</li>
{% endfor %}
</ol>
<ol>
{% for s in mylist2 %}
<li>{{- loop.index0 }} --- {{ s }}</li>
{% endfor %}
</ol>
Fisierul info.tpl din folderul templates:
{% include "header.tpl" %}
<h1>{{ title }}</h1>
<hr>
<a href="/">Home</a>
<h2>{{ msg }}</h2>
Fisierul header.tpl din folderul templates (si inclus de index.tpl si info.tpl) poate sa contina orice inceput valid de document html.
<html>
<!-- orice fel de cod html -->
Folderul static este comprimat si inclus in programul executabil generat de compilatorul Rust folosind biblioteca rust-embed,
Folderul templates este folosit de biblioteca askama la generarea de pagini web.
Programul generat de Rust are 5.1 MB in windows.