exum 0.1.2

A lightweight Axum syntax sugar library
Documentation
# Exum


一个轻量级的 Axum 语法糖库,提供更简洁的路由定义语法。

## 特性


- 🚀 简洁的路由宏语法
- 📦 自动参数提取和类型转换
- 🔧 支持多种HTTP方法
- 🎯 路径参数自动解析
- 📝 查询参数和请求体处理
- ⚡ 省略返回值时默认返回 `impl IntoResponse`
- 🌍 环境自动检测和配置覆盖
- 🔧 环境变量注入支持
- 📁 多环境配置文件管理

## 安装


在 `Cargo.toml` 中添加依赖:

```toml
[dependencies]
exum = "0.1.0"
```

## 快速开始


```rust
use exum::*;

#[get("/hello/:id")]

async fn hello(id: String, #[q] q: String) -> String {
    format!("id: {}, query: {}", id, q)
}

#[post("/users")]

async fn create_user(#[b] user: User) -> String {
    format!("Created user: {:?}", user)
}

// 省略返回值时,默认返回 impl IntoResponse
#[get("/simple")]

async fn simple_handler() {
    "Hello, World!"
}

#[tokio::main]

async fn main() {
    let app = Application::build(ApplicationConfig::default());
    app.run().await;
}
```

## 路由宏


### 支持的HTTP方法


- `#[get(path)]` - GET 请求
- `#[post(path)]` - POST 请求
- `#[put(path)]` - PUT 请求
- `#[delete(path)]` - DELETE 请求
- `#[options(path)]` - OPTIONS 请求
- `#[head(path)]` - HEAD 请求
- `#[trace(path)]` - TRACE 请求
- `#[route(path, method = "METHOD")]` - 自定义方法

### 路径参数


路径参数使用 `:` 前缀或 `{}` 语法:

```rust
#[get("/users/:id")]

async fn get_user(id: String) -> String {
    format!("User ID: {}", id)
}

#[get("/posts/{post_id}/comments/{comment_id}")]

async fn get_comment(post_id: String, comment_id: String) -> String {
    format!("Post: {}, Comment: {}", post_id, comment_id)
}
```

## 参数提取


### 查询参数 (`#[q]`)


使用 `#[q]` 属性自动提取查询参数:

```rust
#[get("/search")]

async fn search(#[q] query: String, #[q] page: Option<i32>) -> String {
    format!("Search: {}, Page: {:?}", query, page)
}

// 支持元组模式
#[get("/search2")]

async fn search2(#[q] (query, page): (String, Option<i32>)) -> String {
    format!("Search: {}, Page: {:?}", query, page)
}
```

### 请求体 (`#[b]`)


使用 `#[b]` 属性处理请求体,支持多种格式:

```rust
use serde::Deserialize;

#[derive(Deserialize)]

struct User {
    name: String,
    age: i32,
}

// JSON 格式(默认)
#[post("/users")]

async fn create_user(#[b] user: User) -> String {
    format!("Created user: {:?}", user)
}

// Form 格式
#[post("/users/form")]

async fn create_user_form(#[b(form)] user: User) -> String {
    format!("Created user from form: {:?}", user)
}

// Multipart 格式
#[post("/users/upload")]

async fn upload_user(#[b(multipart)] user: User) -> String {
    format!("Uploaded user: {:?}", user)
}

// 可选参数
#[post("/users/optional")]

async fn create_user_optional(#[b] user: Option<User>) -> String {
    match user {
        Some(u) => format!("Created user: {:?}", u),
        None => "No user provided".to_string(),
    }
}
```

## 配置


### 手动配置


```rust
use exum::config::ApplicationConfig;

let config = ApplicationConfig {
    addr: [127, 0, 0, 1],
    port: 3000,
};

let app = Application::build(config);
```

### 从配置文件加载


创建 `config.toml` 文件:

```toml
addr = [127, 0, 0, 1]
port = 3000
```

然后在代码中使用:

```rust
use exum::config::ApplicationConfig;

let config = ApplicationConfig::from_file("config.toml");
let app = Application::build(config);
```

### 环境特定配置


Exum 支持环境特定的配置文件覆盖。系统会自动检测当前环境并加载对应的配置文件:

1. **环境检测规则**   - 如果设置了 `EXUM_ENV` 环境变量,则使用该值
   - 否则,在调试模式下使用 `dev`,生产模式下使用 `prod`

2. **配置文件加载顺序**   - 首先加载 `config.toml` 作为基础配置
   - 然后加载 `config.{env}.toml` 并覆盖基础配置

示例:
```toml
# config.toml (基础配置)

addr = [127, 0, 0, 1]
port = 8080
database_url = "postgres://localhost:5432/mydb"
```

```toml
# config.dev.toml (开发环境配置)

port = 3000
database_url = "postgres://localhost:5432/mydb_dev"
```

```toml
# config.prod.toml (生产环境配置)

addr = [0, 0, 0, 0]
database_url = "${DATABASE_URL}"
```

### 环境变量注入


配置文件支持环境变量注入,使用 `${VARIABLE_NAME}` 语法:

```toml
# config.toml

database_url = "${DATABASE_URL}"
api_key = "${API_KEY}"
port = "${PORT:-8080}"  # 支持默认值
```

在代码中自动加载配置:
```rust
use exum::config::ApplicationConfig;

// 自动加载配置,包含环境变量注入和环境特定配置
let config = ApplicationConfig::load();
let app = Application::build(config);
```

### #[main] 宏


Exum 提供了 `#[main]` 宏来自动注入 Application 的构建和运行代码:

```rust
#[main]

async fn main() {
    // 这里可以添加自定义逻辑
    println!("服务器启动中...");
}

// 或者从配置文件加载配置
#[main(config = "config.toml")]

async fn main() {
    // 这里可以添加自定义逻辑
    println!("使用配置文件启动服务器...");
}
```

`#[main]` 宏会自动注入以下代码:
- `#[tokio::main]` 属性
- `Application::build()` 调用
- `app.run().await` 调用


## 完整示例


```rust
use exum::*;
use serde::Deserialize;

#[derive(Deserialize, Debug)]

struct CreateUserRequest {
    name: String,
    email: String,
}

#[get("/users/:id")]

async fn get_user(id: String) -> String {
    format!("Getting user with ID: {}", id)
}

#[post("/users")]

async fn create_user(#[b] user: CreateUserRequest) -> String {
    format!("Creating user: {:?}", user)
}

#[put("/users/:id")]

async fn update_user(id: String, #[b] user: CreateUserRequest) -> String {
    format!("Updating user {}: {:?}", id, user)
}

#[delete("/users/:id")]

async fn delete_user(id: String) -> String {
    format!("Deleting user with ID: {}", id)
}

#[get("/search")]

async fn search(#[q] query: String, #[q] page: Option<i32>) -> String {
    format!("Searching for '{}' on page {:?}", query, page)
}

#[tokio::main]

async fn main() {
    let app = Application::build(ApplicationConfig::default());
    app.run().await;
}
```

## Features


- `deref-app`: 为 `Application` 实现 `Deref` trait,可以直接访问底层的 `Router`
- `full`: 包含所有特性

## 许可证


MIT License