当前位置: 代码迷 >> 综合 >> Rust:一个简单的 Web 应用程序示例
  详细解决方案

Rust:一个简单的 Web 应用程序示例

热度:70   发布时间:2023-12-12 15:25:01.0

源代码

编写 Web 应用程序,输入两个自然数,输出其最大公约数。

Cargo.toml 文件

[package]
name = "testweb"
version = "0.1.0"
edition = "2018"# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html[dependencies]
iron = "0.5.1"
mime = "0.2.3"
router = "0.5.1"
urlencoded = "0.5.0"

main.rs 文件:

extern crate iron;
#[macro_use] extern crate mime;use iron::prelude::*;
use iron::status;
use iron::Response;extern crate router;
use router::Router;use std::str::FromStr;
use urlencoded::UrlEncodedBody;fn main() {
    let mut router = Router::new();router.get("/", get_form, "root");router.post("/gcd", post_gcd, "gcd");println!("serving on http://localhost:8080...");Iron::new(router).http("0.0.0.0:8080").unwrap();
}fn get_form(request: &mut Request) -> IronResult<Response> {
    let mut response = Response::new();response.set_mut(status::Ok);response.set_mut(mime!(Text/Html; Charset=Utf8));response.set_mut(r#"<title>GCD Calculator</title><form action="/gcd" method="post"><input type="text" name="n"/><input type="text" name="n"/><button type="submit">Compute GCD</button></form>"#);Ok(response)
}fn post_gcd(request: &mut Request) -> IronResult<Response> {
    let mut response = Response::new();let form_data = match request.get_ref::<UrlEncodedBody>() {
    Err(e) => {
    response.set_mut(status::BadRequest);response.set_mut(format!("Error parsing form data: {:?}\n", e));return Ok(response);}Ok(map) => map};let unparsed_numbers = match form_data.get("n") {
    None => {
    response.set_mut(status::BadRequest);response.set_mut(format!("form data has no 'n' parameter\n"));return Ok(response);}Some(nums) => nums};let mut numbers = Vec::new();for unparsed in unparsed_numbers {
    match u64::from_str(&unparsed) {
    Err(_) => {
    response.set_mut(status::BadRequest);response.set_mut(format!("Value for 'n' paramster not a number: {:?}\n",unparsed));return Ok(response);}Ok(n) => {
     numbers.push(n);}}}let mut d = numbers[0];for m in &numbers[1..] {
    d = gcd(d, *m);}response.set_mut(status::Ok);response.set_mut(mime!(Text/Html; Charset=Utf8));response.set_mut(format!("The greatest comon divisor of the numbers {:?} is <b>{}</b>\n",numbers, d));Ok(response)
}fn gcd(mut x: u64, mut y: u64) -> u64 {
    loop {
    if x == y {
     return x; }if x > y {
     x = x - y; }if x < y {
     y = y - x; }}
}

代码注释

主程序:

fn main() {
    // Router 可把网页请求路由指定的函数。let mut router = Router::new();// 收到 URL地址 "/" 的 get 请求,调用 get_form 函数,"root" 是 route_id。router.get("/", get_form, "root");// 收到 URL地址 "/" 的 post 请求,调用 post_gcd 函数,"gcd" 是 route_id。router.post("/gcd", post_gcd, "gcd");println!("serving on http://localhost:8080...");Iron::new(router).http("0.0.0.0:8080").unwrap();
}

get_form 函数:

fn get_form(request: &mut Request) -> IronResult<Response> {
    // get_form 返回一个 html 网页,网页内容封装在 Response 结构中。let mut response = Response::new();// 返回网页的状态。response.set_mut(status::Ok);// 设置网页的类型和属性。如果不设置这个,即使后面设置的文本符合 html 语法,// 浏览器也不会把它解释成为渲染为网页。response.set_mut(mime!(Text/Html; Charset=Utf8));// 设置 html 网页的文本。response.set_mut(r#"<title>GCD Calculator</title><form action="/gcd" method="post"><input type="text" name="n"/><input type="text" name="n"/><button type="submit">Compute GCD</button></form>"#);Ok(response)
}

post_gcd 函数:

fn post_gcd(request: &mut Request) -> IronResult<Response> {
    // get_form 返回一个 html 网页,网页内容封装在 Response 结构中。let mut response = Response::new();// 从 request 中获取网页内容。let form_data = match request.get_ref::<UrlEncodedBody>() {
    Err(e) => {
    // 展示了遇到错误时,如何生成一个携带错误信息的网页。response.set_mut(status::BadRequest);response.set_mut(format!("Error parsing form data: {:?}\n", e));return Ok(response);}// 解析出网页数据,保存到变量 map 中。Ok(map) => map};/* 示例数据, json 格式数据form_data = {"n": ["123", "456"]}*/// 从let unparsed_numbers = match form_data.get("n") {
    None => {
    response.set_mut(status::BadRequest);response.set_mut(format!("form data has no 'n' parameter\n"));return Ok(response);}Some(nums) => nums};/* 示例数据,应该是 &str 类型unparsed_numbers = ["123", "456"]*/// 把数据从 &str 解析到 Vec 动态数组中。let mut numbers = Vec::new();for unparsed in unparsed_numbers {
    match u64::from_str(&unparsed) {
    Err(_) => {
    response.set_mut(status::BadRequest);response.set_mut(format!("Value for 'n' paramster not a number: {:?}\n",unparsed));return Ok(response);}Ok(n) => {
     numbers.push(n);}}}let mut d = numbers[0];for m in &numbers[1..] {
    d = gcd(d, *m);}// 返回结果封装到 response 结构中。response.set_mut(status::Ok);response.set_mut(mime!(Text/Html; Charset=Utf8));response.set_mut(format!("The greatest comon divisor of the numbers {:?} is <b>{}</b>\n",numbers, d));Ok(response)
}
  相关解决方案