「这是我参与11月更文挑战的第 16 天,活动详情查看:2021最后一次更文挑战」
新内容
回顾了一下 2021 Rust 版本发布时,新的程序加入了哪些新的东西:
anyhow- 为人类设计的错误处理库,因为以前的库真的都不行。async/await- 用于表达异步计算的新语法:像网络服务器一样!catch_unwind- 一个 panic线程 不应该让你的整个服务器崩溃! 优雅处理panic-compression- 每个响应都将被DEFLATE压缩,仅仅是因为我们可以。- Rust 2021 - Rust的未来。
- 状态管理 - 我们将使用 协议扩展 来访问应用程序的状态,而不是全局变量。
- 链路追踪 - log 已经是过时了。现在所有的cool programmer都在使用 tracing。
- 单元测试 - 学习如何为你的处理程序编写异步单元测试。
初始化
先把你的环境弄好,这个官网有。一旦你的环境设置好了,就可以开始一个新的项目:
> cargo new simple-todo
Created binary (application) `simple-todo` package
> cd simple-todo
> cargo run
Compiling simple-todo v0.1.0 (/home/deciduously/code/simple-todo)
Finished dev [unoptimized + debuginfo] target(s) in 0.19s
Running `target/debug/simple-todo
Hello, world!
打开 Cargo.toml:
[package]
edition = "2021"
rust-version = "1.56"
name = "simple-todo"
version = "0.1.0"
[dependencies]
anyhow = "1"
backtrace = "0.3"
clap = {version = "3.0.0-beta.5", features = ["color"] }
flate2 = "1"
futures = "0.3"
hyper = { version = "0.14", features = ["full"] }
lazy_static = "1.4"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tera = "1"
tokio = { version = "1", features = ["full"] }
uuid = { version = "0.8", features = ["serde", "v4"] }
[dev-dependencies]
pretty_assertions = "0.7"
select = "0.5"
Good to go!
Entrypoint
整个应用程序将在 src/main.rs 中运行。首先要添加导入 crate :
use anyhow::Result;
use backtrace::Backtrace;
use clap::Parser;
use flate2::{write::ZlibEncoder, Compression};
use futures::{future::FutureExt, Future};
use hyper::http;
use lazy_static::lazy_static;
use serde::Serialize;
use std::{
cell::RefCell,
convert::Infallible,
io::Write,
panic::AssertUnwindSafe,
path::PathBuf,
sync::{Arc, RwLock},
};
use tera::Tera;
use uuid::Uuid;
允许用户指定在哪里运行他们的应用程序,这样用户体验会好很多。clap库提供了一种方便的方法来指定结构中的命令行参数。这个功能还在测试阶段,但很快就会稳定下来。我们可以创建一个结构并使用解析器功能来生成选项。
#[derive(Parser)]
#[clap(version = concat!(env!("CARGO_PKG_VERSION")), about = "Serve a TODO list application.")]
struct Args {
#[clap(
short,
long,
about = "Address to bind the server to.",
env,
default_value = "0.0.0.0"
)]
address: String,
#[clap(short, long, about = "Port to listen on.", env, default_value = "3000")]
port: u16,
}
当运行时没有附带没有任何参数,服务器将绑定到:0.0.0.0:3000,这是一个合理的默认值。这允许用户使用ADDRESS和PORT环境变量或 -a/-address 和 -p/-port 命令行参数。它还提供了一个很好的 --help 提示:
simple-todo 0.1.0
Serve a TODO list application.
USAGE:
todo-mvp-rust [OPTIONS]
OPTIONS:
-a, --address <ADDRESS> Address to bind the server to. [env: ADDRESS=] [default: 0.0.0.0]
-h, --help Print help information
-p, --port <PORT> Port to listen on. [env: PORT=] [default: 3000]
-V, --version Print version information
我们的 main() 将只是解析这些参数,并将它们传递给我们的应用程序。
fn main() -> Result<()> {
let args = Args::parse();
app(args)?;
Ok(())
}