# Rust 代码风格规范(用于 AI 生成代码规则) ## 1. 基础风格 * 使用 **Rust 2021 edition**。 * 缩进统一 **4 空格**,不使用 Tab。 * 每行代码长度建议不超过 **100 字符**。 * **花括号风格**: ```rust fn example() { // good } ``` * 表达式尽量简洁,必要时换行,参数链式调用时 **缩进对齐**。 --- ## 2. 模块与导入 * 模块顶部导入,按以下顺序分组,组间空一行: 1. **标准库 (`std::..`)** 2. **第三方库 (`chrono`, `sea_orm`, `tokio` 等)** 3. **本地 crate (`crate::..`)** * 统一使用 **显式导入**,禁止 `use super::*` 或 `use crate::*`。 * 相同模块导入合并: ```rust use sea_orm::{EntityTrait, QueryFilter, ColumnTrait}; ``` --- ## 3. 命名规则 * **模块 / 文件名**:`snake_case` * **函数 / 变量名**:`snake_case` * **结构体 / 枚举名**:`PascalCase` * **常量**:`UPPER_CASE` * **DTO/请求体/响应体**后缀:`Doc` / `Req` / `Resp` 示例: ```rust pub struct ScheduleJobDoc { .. } pub struct CreateReq { .. } pub struct PageResp { .. } ``` --- ## 4. 文档与注释 * 每个 **模块** 顶部使用 `//!` 写模块职责说明。 * 每个 **公开函数** 必须有 `///` 注释,简述用途与主要逻辑。 * 内部复杂逻辑使用 `//` 单行注释解释。 * 中文注释优先,避免英文缩写晦涩难懂。 示例: ```rust /// 创建任务: /// - 校验 cron 表达式 /// - 校验唯一性 /// - 入库后注册调度器 pub async fn create(..) -> Result<..> { .. } ``` --- ## 5. 错误处理 * 错误类型统一用 **自定义错误枚举**(如 `AppError`)。 * 不直接 `unwrap()` / `expect()`,统一返回 `Result`。 * 错误信息应清晰且面向用户,内部日志保留技术细节。 --- ## 6. 日志规范 * 使用 `tracing` 库,必须带 `target`。 * 统一格式:`模块.操作.状态` * 日志字段使用 `key = %value` 或 `key = ?value`,避免拼接字符串。 示例: ```rust info!(target = "udmin", id = %job_id, enabled = %enabled, "schedule_jobs.update.persisted"); error!(target = "udmin", id = %job_id, error = %e, "schedule_jobs.run.failed"); ``` --- ## 7. 异步与数据库 * 使用 `async fn`,返回 `Result`。 * SeaORM 查询使用链式写法,**按字段过滤**时一行一个 filter。 * 分页/排序明确写出,不隐式。 示例: ```rust let jobs = schedule_job::Entity::find() .filter(schedule_job::Column::Enabled.eq(true)) .order_by_desc(schedule_job::Column::UpdatedAt) .paginate(db, page_size); ``` --- ## 8. 结构体组织 * DTO / 请求体 / 响应体 放在模块前部。 * Service 函数按生命周期顺序:`list → create → update → remove → init`。 * 工具函数(如 `build_executor_for_job`、`now_fixed_offset`)放在模块最后。 --- ## 9. 闭包与异步执行器 * 使用 `Arc::new(move || { Box::pin(async move { .. }) })` 形式。 * 避免重复 clone,大对象提前 clone 一次再 move 进闭包。 * 返回 `Pin + Send>>`。 --- ## 10. 时间与 ID * 时间统一用 `chrono::Utc::now().with_timezone(&FixedOffset::east_opt(0).unwrap())`,可封装成 `now_fixed_offset()`。 * ID 统一使用 `id: Set(crate::utils::generate_id())`。 --- ## 11. 统一返回体 * 分页接口统一返回 `PageResp`。 * 单条数据返回 DTO(如 `ScheduleJobDoc`)。 * 删除接口返回 `Result<(), AppError>`。 --- ## 12. 代码整洁性 * 避免嵌套过深,必要时提前 `return`。 * 冗余 clone 使用 `.clone()` 仅在必须时。 * 枚举 / match 分支完整,必要时加 `_ => {}` 显式忽略。 --- ⚡ 总结: 生成的代码必须 **简洁、清晰、分组有序、日志一致、错误优雅**,看起来像经验丰富的 Rust 高手写的生产级代码。