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

该博客介绍了一个使用Rust语言编写的Web应用程序,该程序接收两个自然数作为输入,然后计算并返回它们的最大公约数(GCD)。应用基于Iron框架构建,通过GET和POST请求处理页面展示和数据提交。用户输入通过表单提交,服务器端进行数据解析和有效性检查,最后计算GCD并显示结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源代码

编写 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)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

许野平

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值