「simple TODO APP in Rust」初始化项目

194 阅读2分钟

「这是我参与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(())
}