Rust web 框架 axum (五): 每个功能独立一个文件

更新日期: 2023-12-20 阅读次数: 815 字数: 530 分类: rust

之前为了练手把所有的 Axum rust 代码都写在 main.rs 这一个主文件中。

随着功能的增多,发现几点不便:

  • 代码行数过多,不方便查找指定功能的代码
  • 不同功能的类似数据结构需要分别定义,为了避免重名,增加了功能名前缀,但是带来的影响是类型名过长,代码丑陋无比
  • 新增功能时,复制/修改既有代码也不方便

目标

一个 Axum 项目中,有多个子功能,每个子功能在不同的文件中实现。

契机

正好在写枯燥无比的 Android 界面代码时,产生了一个小工具的需求, 即,将 Android 样式代码剥离出 styles.xml 文件,于是在写这个功能的时候, 就顺手将既有的 Axum 项目代码重构了一下,改成了多文件的结构。

最终成品:Android XML Layout Inline 样式转换

用 rust 来做字符串处理,还是挺舒服的。

handler 文件 android_style.rs

新建一个独立的 rust handler 代码文件,例如 android_style.rs。注意:

  • 开放给 main.rs 调用的函数需要加 pub 声明为 public。否则为私有,无法外部调用
  • 这些 pub 函数用到的参数类型,也需要定义为 pub 类型
use askama::Template;
use axum::{
    Form,
};
use serde::Deserialize;

#[derive(Deserialize)]
pub struct FormInput {
    input: String,
}

#[derive(Template)]
#[template(path = "convert_android_style.html")]
pub struct HtmlTemplate {
    input: String,
    output: String,
}

pub async fn handle_get() -> HtmlTemplate {
    let input = String::from(r#"android:layout_width="148dp"
android:layout_height="55dp"
android:layout_marginTop="8dp"
"#);
    HtmlTemplate { input: input, output: String::from("") }
}

pub async fn handle_post(Form(form_input): Form<FormInput>) -> HtmlTemplate {
    //println!("{}", form_input.input);
    let output = convert(&form_input.input);
    HtmlTemplate { input: form_input.input, output: output}
}

main.rs

在 main.rs 就可以直接调用 android_style.rs 中的 pub 函数了。

mod android_style;

let web_routes = Router::new()
	.route("/android-style",
		get(android_style::handle_get).post(android_style::handle_post))
	.fallback(fallback);

mod 跟 use 的区别

上面引用其他文件中代码用到了 mod 关键字,那么这个 mod 跟 use 有何区别呢?

  • mod 即 module, 可以理解为一个 crate 内的不同模块
  • use 代表使用一个其他 crate

查看合集

📖 Rust web 框架 axum 教程:从入门到遥遥领先

tags: axum

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式