之前为了练手把所有的 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 教程:从入门到遥遥领先
关于作者 🌱
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式