exum 0.1.14

A lightweight Axum syntax sugar library
Documentation
# #[main] 宏


`#[main]` 宏是 Exum 框架的核心功能之一,它自动处理应用程序的初始化和运行逻辑,让开发者可以专注于业务代码。

## 基本用法


### 最简单的使用方式


```rust
#[main]

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

### 使用配置文件


```rust
#[main(config = "config.toml")]

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

## 自动注入的功能


`#[main]` 宏会自动注入以下代码:

### 1. 自动添加 `#[tokio::main]`

- 自动为 `main` 函数添加 `#[tokio::main]` 属性
- 无需手动处理异步运行时配置

### 2. 自动加载配置

- 如果没有指定配置文件,使用 `ApplicationConfig::load()` 自动加载默认配置
- 如果指定了配置文件路径,使用 `ApplicationConfig::from_file(path)` 加载指定配置

> 详细配置加载逻辑请参考:[配置管理文档]./configuration.md

### 3. 自动构建 Application

- 自动创建 `Application::build(config)` 调用
- 配置对象会自动传递给构建器

### 4. 自动运行应用

- 自动添加 `app.run().await` 调用
- 确保应用程序正确启动和运行

## `app_chain!` 宏的配合使用


`#[main]` 宏内部可以配合 `app_chain!` 宏来构建复杂的应用链:

```rust
#[main]

async fn main() {
    app_chain!(app, {
        route("/custom", axum::routing::get(|| async { "Custom route" })),
        nest("/api", axum::Router::new().route("/users", axum::routing::get(|| async { "Users API" }))),
        layer(tower::ServiceBuilder::new()
            .layer(tower_http::trace::TraceLayer::new_for_http()))
    });
}
```

`app_chain!` 宏的语法是逗号分隔的方法调用列表,每个方法调用都会转换为 `app.app = app.app.方法名(...)` 的形式。

## 展开后的代码


`#[main]` 宏展开后的代码相当于:

```rust
#[tokio::main]

async fn main() {
    let _CONFIG = ApplicationConfig::load(); // 或 from_file()
    let mut app = Application::build(_CONFIG);
    {
        // 用户自定义的代码块
        println!("服务器启动中...");
    }
    app.run().await;
}
```

## 配置文件的自动发现


当使用 `#[main]` 宏时,框架会自动尝试从以下位置加载配置文件:

1. 如果指定了 `config = "路径"`,则从指定路径加载
2. 如果没有指定,按以下顺序加载:
   - 首先加载 `./config.toml` 作为基础配置
   - 然后根据当前环境(如 `prod``dev`)加载对应的环境配置文件 `./config.{env}.toml`
   - 环境配置文件会覆盖基础配置中的相同字段
   - 最后注入环境变量中的配置值
3. 如果都没有找到,使用默认配置

## 优势


使用 `#[main]` 宏的优势:

1. **简化启动代码**:无需重复编写启动逻辑
2. **统一配置管理**:自动处理配置加载
3. **减少错误**:避免忘记添加必要的启动代码
4. **更好的可维护性**:启动逻辑集中管理

## 注意事项


- `#[main]` 宏只能用于 `main` 函数
- 函数必须是 `async`- 宏会替换整个函数体,但保留用户自定义的代码块