源代码
编写 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)
}