O aplicatie web in Rust

Categorii: Programare

18-Mar-2021 17:47 - 124 vizionari

Imi place Rust!

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.


Ultimele pagini: RSS

Alte adrese de Internet

Categorii

Istoric


Atentie: Continutul acestui server reprezinta ideile mele si acestea pot fi gresite.