Skip to main content

Crate trait_kit

Crate trait_kit 

Source
Expand description

trait-kit — 模块标准接口与能力管理中心

提供模块定义标准接口和 Kit 能力管理中心的轻量实现。

trait-kit logo

CI crates.io docs.rs downloads MIT licensed MSRV

中文 | English

trait-kit 是一个轻量级 Rust 库,提供标准化的模块接口和集中式能力与配置管理中心(Kit)。采用 typestate 模式(Kit<Unbuilt>Kit<Ready>)进行构建时验证,基于 RefCell 的内部可变性实现单线程设计(!Sync)。


§✨ 核心特性

  • 标准化模块接口ModuleMeta + AutoBuilder trait 定义统一契约,配合 impl_module_meta! / impl_auto_builder! 宏可一行声明模块。
  • Typestate 构建验证Kit<Unbuilt> 注册模块和配置;kit.build() 验证依赖图(环检测、缺失依赖检测)并返回 Kit<Ready>,构建错误在应用启动前暴露。
  • 类型安全的能力检索 — 能力按模块类型存储和检索(kit.require::<LoggerModule>()),而非字符串键。无需 downcast,无需运行时查找。
  • 配置中心kit.set_config(value) / kit.config::<C>() 通过 TypeMap(以 TypeId 为键)存储和检索类型化配置,无需 ConfigKeyConfigHandle 样板代码。
  • 可选 confers 集成 — 四级 feature flag 集成 confers,支持 derive 宏配置加载、热重载订阅和 XChaCha20-Poly1305 加密配置存储。
  • AsyncKit 异步支持async feature 提供 AsyncKit,支持 Send + Sync 的异步能力管理,适用于数据库连接池、HTTP 客户端等异步初始化场景。
  • ICU4X 国际化 — 内置 ICU4X 支持,提供区域感知的数字、日期、复数和排序能力,以及基于 Fluent FTL 的中英文消息翻译(tr())。
  • 最小依赖 — 仅 thiserroricuwriteablesys-locale 为必需依赖。confersserdeserde_json 均为可选,仅在启用对应 feature 时引入。
  • #![deny(unsafe_code)] — 整个 crate 无任何 unsafe 代码。

§📦 快速开始

§MSRV

最低支持 Rust 版本:1.91

§安装

cargo add trait-kit

§基础使用

定义一个 logger 模块,注册、构建 Kit,然后检索能力:

use std::sync::Arc;
use trait_kit::impl_module_meta;
use trait_kit::prelude::*;

// 1. 定义能力(任意 Clone 类型)
struct StdoutLogger;
impl StdoutLogger {
    fn info(&self, msg: &str) {
        println!("[LOG] {msg}");
    }
}

// 2. 定义模块(宏一行声明 ModuleMeta)
struct LoggerModule;
impl_module_meta!(LoggerModule, "logger");
impl AutoBuilder for LoggerModule {
    type Capability = Arc<StdoutLogger>;
    type Error = TraitKitError;
    fn build(_kit: &Kit) -> Result<Self::Capability, Self::Error> {
        Ok(Arc::new(StdoutLogger))
    }
}

// 3. 注册、构建、使用
fn main() {
    let mut kit = Kit::new();
    kit.register::<LoggerModule>().unwrap();
    let kit = kit.build().unwrap();

    let logger = kit.require::<LoggerModule>().unwrap();
    logger.info("Hello from trait-kit!");
    assert!(kit.contains::<LoggerModule>());
}

§🔧 用法

§带配置的模块

配置是存储在 Kit 的 TypeMap 中的类型化值。模块在构建时通过 kit.config::<C>() 检索:

use std::sync::Arc;
use trait_kit::impl_module_meta;
use trait_kit::prelude::*;

#[derive(Clone, Debug)]
struct DbConfig {
    url: String,
    max_connections: u32,
}

struct DbPool {
    config: DbConfig,
}

struct DbPoolModule;
impl_module_meta!(DbPoolModule, "db-pool");
impl AutoBuilder for DbPoolModule {
    type Capability = Arc<DbPool>;
    type Error = TraitKitError;
    fn build(kit: &Kit) -> Result<Self::Capability, Self::Error> {
        let config: DbConfig = kit.config()?;
        Ok(Arc::new(DbPool { config }))
    }
}

fn main() {
    let mut kit = Kit::new();
    kit.set_config(DbConfig {
        url: "postgres://localhost".into(),
        max_connections: 10,
    });
    kit.register::<DbPoolModule>().unwrap();
    let kit = kit.build().unwrap();

    let pool = kit.require::<DbPoolModule>().unwrap();
    assert_eq!(pool.config.max_connections, 10);
}

§带依赖的模块

模块通过 impl_module_meta! 宏声明依赖。Kit 在构建时验证依赖图,并按拓扑顺序构造模块:

use std::sync::Arc;
use trait_kit::impl_module_meta;
use trait_kit::prelude::*;

struct Logger;
impl Logger {
    fn info(&self, msg: &str) { println!("[LOG] {msg}"); }
}

struct LoggerModule;
impl_module_meta!(LoggerModule, "logger");
impl AutoBuilder for LoggerModule {
    type Capability = Arc<Logger>;
    type Error = TraitKitError;
    fn build(_kit: &Kit) -> Result<Self::Capability, Self::Error> {
        Ok(Arc::new(Logger))
    }
}

struct Storage {
    _logger: Arc<Logger>,
}

struct StorageModule;
impl_module_meta!(StorageModule, "storage", deps = [LoggerModule]);
impl AutoBuilder for StorageModule {
    type Capability = Arc<Storage>;
    type Error = TraitKitError;
    fn build(kit: &Kit) -> Result<Self::Capability, Self::Error> {
        let logger = kit.require::<LoggerModule>()?;
        Ok(Arc::new(Storage { _logger: logger }))
    }
}

fn main() {
    let mut kit = Kit::new();
    kit.register::<LoggerModule>().unwrap();
    kit.register::<StorageModule>().unwrap();
    let kit = kit.build().unwrap();

    let storage = kit.require::<StorageModule>().unwrap();
    let _ = storage;
}

§Kit API 总览

方法可用阶段说明
Kit::new()创建空的 Kit<Unbuilt>
kit.register::<M>()Kit<Unbuilt>注册模块以进行构建。
kit.register_lazy::<M>()Kit<Unbuilt>注册延迟构建(首次 require() 时构造)。
kit.register_multi::<M>()Kit<Unbuilt>注册多绑定(相同能力类型)。
kit.register_as::<M>()Kit<Unbuilt>按接口类型注册(dyn Trait)。
kit.register_if::<M>()Kit<Unbuilt>条件注册(运行时谓词控制)。
kit.register_if_toggle::<M>()Kit<Unbuilt>toggle 特性开关条件注册。
kit.register_lifecycle::<M>()Kit<Unbuilt>注册模块的生命周期钩子。
kit.register_health_check::<M>()Kit<Unbuilt>注册模块的健康检查。
kit.with_observer(obs)Kit<Unbuilt>附加 BuildObserver 构建回调。
kit.decorate::<M>(f)Kit<Unbuilt>构建后能力包装/增强。
kit.set_config::<C>(value)两者皆可存储类型化配置值。
kit.config::<C>()两者皆可检索配置值(克隆)。
kit.load_config::<C>()Kit<Unbuilt> confers通过 Configurable::load() 加载配置。
kit.load_and_validate::<C>()Kit<Unbuilt> confers加载配置并验证,失败不存入。
kit.load_config_with::<C>(vars)Kit<Unbuilt> confers加载配置并做 ${VAR} 变量替换。
kit.snapshot_config::<C>()Kit<Unbuilt> confers快照当前配置(返回是否成功)。
kit.restore_config::<C>()Kit<Unbuilt> confers回滚配置到最近快照。
kit.has_snapshot::<C>()Kit<Unbuilt> confers检查指定类型快照是否存在。
kit.subscribe::<C>(cb)两者皆可 reload订阅配置热重载回调。
kit.reload_config::<C>()两者皆可 reload重新加载配置并通知订阅者。
kit.set_encrypted(val, key)Kit<Unbuilt> encryption加密存储配置。
kit.enable_toggle(key, bool)两者皆可 toggle设置特性开关。
kit.is_toggle_enabled(key)两者皆可 toggle查询特性开关状态。
kit.build()Kit<Unbuilt>验证依赖图并构建所有模块 → Kit<Ready>
kit.require::<M>()Kit<Ready>检索能力(缺失时报错)。
kit.require_ref::<M>()Kit<Ready>零拷贝能力检索(Ref<'_, Cap>)。
kit.optional::<M>()Kit<Ready>检索能力(缺失时返回 None)。
kit.require_all::<M>()Kit<Ready>返回所有多绑定能力。
kit.resolve::<I>()Kit<Ready>按接口类型检索(Arc<I>)。
kit.contains::<M>()Kit<Ready>检查能力是否已构建。
kit.contains_config::<C>()Kit<Ready>检查配置值是否存在。
kit.get_encrypted::<C>(key)Kit<Ready> encryption解密检索配置。
kit.health_check::<M>()Kit<Ready>运行模块健康检查。
kit.health_report()Kit<Ready>返回所有模块的健康报告。
kit.shutdown()Kit<Ready>按拓扑逆序运行 on_shutdown

§🏷️ 特性标志

Feature启用说明
default无额外特性,仅核心 Module + Kit
asyncAsyncKitSend + Sync 异步能力管理,无需额外依赖。
confersdep:confers, dep:serdeConfigurable + ModuleConfig trait + Config derive 宏再导出。
reloadconfers, confers/watchsubscribe / reload_config 热重载 API。
encryptionconfers, confers/encryptionset_encrypted / get_encrypted 加密配置存储。
interface接口/实现分离:register_as / resolve 支持 dyn Trait 类型擦除注册与检索。
lifecycle生命周期钩子:on_ready(构建后)+ on_shutdown(清理)。
health健康检查:HealthCheck trait + HealthStatus 状态报告。
scope作用域依赖:Scope 每请求实例隔离。
toggle特性开关:运行时字符串键控的模块启用/禁用。
observer构建可观测:BuildObserver 回调(开始/完成/错误)。
decorator模块装饰器:构建后能力包装/增强。
shutdown优雅关闭协调器:分阶段有序关闭 + 超时强退。
i18ndep:icu, dep:writeable, dep:sys-localeICU4X 国际化:本地化数字/日期/复数/排序格式化。

Cargo.toml 中启用所需级别:

[dependencies]
trait-kit = { version = "0.4", features = ["encryption"] }

§⚙️ 配置:confers 集成

trait-kit 通过三级 feature flag 集成 confers 0.5。每个级别继承前一级别,形成分层能力系统。

§confers 特性标志

Feature启用说明
confersdep:confers, dep:serdeConfigurable + ModuleConfig trait + Config derive 宏再导出。
reloadconfers, confers/watchsubscribe / reload_config API。
encryptionconfers, confers/encryptionset_encrypted / get_encrypted API。

§三级继承体系

  1. 模块能力继承(第一层):ModuleConfig trait 声明 PATHdefault_value(),将配置类型绑定到模块的配置路径。

  2. Cargo feature 继承(第二层):每个 feature 级别继承前一级别(encryptionreloadconfers)。启用高级别会自动启用所有低级别。

  3. 配置值继承(第三层):加密密钥通过 HKDF 从 ModuleConfig::PATH 派生,因此同一主密钥可为不同模块生成不同的字段密钥。

§第一级:配置加载模式

定义 Configurable 实现,桥接 confers 的 #[derive(Config)] 宏:

use trait_kit::prelude::*;
use trait_kit::kit::Config;

#[derive(Debug, Clone, PartialEq, serde::Deserialize, Config)]
#[config(env_prefix = "APP_")]
struct AppConfig {
    #[config(default = "localhost".to_string())]
    host: String,
}

impl Configurable for AppConfig {
    fn load() -> Result<Self, Box<dyn std::error::Error>> {
        Ok(AppConfig::load_sync()?)
    }
}

let kit = Kit::new();
kit.load_config::<AppConfig>()?;  // 通过 confers 从环境变量/默认值加载
let kit = kit.build()?;
let config: AppConfig = kit.config()?;

§第二级:模块配置元数据

添加 ModuleConfig 以声明配置路径和默认值:

use trait_kit::kit::config::ModuleConfig;

impl ModuleConfig for AppConfig {
    const PATH: &'static str = "config/app.toml";
    fn default_value() -> Self {
        Self { host: "localhost".to_string() }
    }
}

§第三级:热重载订阅

订阅配置重载时触发的回调:

use std::cell::Cell;
use std::rc::Rc;

let kit = Kit::new();
let called = Rc::new(Cell::new(false));
let called_clone = Rc::clone(&called);
kit.subscribe::<AppConfig>(move || {
    called_clone.set(true);
});

kit.reload_config::<AppConfig>()?;  // 通过 Configurable::load 重载,通知订阅者
assert!(called.get());

§第四级:加密配置存储

使用 XChaCha20-Poly1305 加密静态配置。加密密钥通过 HKDF 从主密钥和 ModuleConfig::PATH 派生:

let kit = Kit::new();
let secret = AppConfig { host: "production-db".to_string() };
let master_key = [0u8; 32]; // 32 字节主密钥

kit.set_encrypted(&secret, &master_key)?;
let kit = kit.build()?;

// 只有正确的主密钥才能解密
let decrypted: AppConfig = kit.get_encrypted(&master_key)?;
assert_eq!(decrypted, secret);

§🏗️ 架构

graph TB
    subgraph core["core — 核心接口"]
        MM[ModuleMeta<br/>名称 + 依赖声明]
        AB[AutoBuilder<br/>同步构建]
        AAB[AsyncAutoBuilder<br/>异步构建]
        LC[Lifecycle<br/>on_ready + on_shutdown]
        HC[HealthCheck<br/>HealthStatus 报告]
        OBS[BuildObserver<br/>构建回调]
    end

    subgraph kit["kit — 能力管理中心"]
        K[Kit&lt;Unbuilt&gt; → Kit&lt;Ready&gt;]
        DG[DependencyGraph<br/>环检测 + 拓扑排序]
        TM[TypeMap<br/>TypeId 键值存储]
        CFG[Config<br/>confers 集成]
        SC[Scope<br/>作用域隔离]
    end

    subgraph async_kit["async_kit — 异步能力管理"]
        AK[AsyncKit&lt;Unbuilt&gt; → AsyncKit&lt;Ready&gt;]
        ATM[AsyncTypeMap<br/>Arc&lt;RwLock&gt; 存储]
    end

    subgraph i18n_mod["i18n — ICU4X 国际化 + Fluent 翻译"]
        I18N["数字 / 日期 / 复数 / 排序 / tr()"]
    end

    MM --> K
    AB --> K
    AAB --> AK
    LC --> K
    HC --> K
    OBS --> K
    K --> DG
    K --> TM
    K --> CFG
    K --> SC
    AK --> ATM

核心设计

  • Typestate 模式Kit<Unbuilt>Kit<Ready>,构建时验证依赖图,运行时零开销。
  • 内部可变性:基于 RefCell,单线程 !Sync 设计,避免锁开销。AsyncKit 使用 Arc<RwLock> 支持多线程。
  • 三级 Feature 继承(confers 集成):
graph LR
    C[confers] --> R[reload]
    R --> E[encryption]

§💡 为什么选择 trait-kit?

trait-kit 定位在“手动装配“和“完整 DI 框架“之间:

方案优点缺点
手动装配简单,无依赖。模式不统一,每个项目各自为政。
trait-kit标准化模式,类型安全,轻量级。仍需显式声明依赖关系。
完整 DI(shaku 等)自动解析,更少胶水代码。依赖更重,魔法行为,调试困难。

trait-kit 提供 DI 框架的标准化,同时保持手动装配的显式性


§🤝 贡献

§构建要求

  • Rust 1.91 或更高版本(stable)。
  • 无需外部工具链(无 protoc、无 openssl、无系统库)。

§开发命令

# 运行所有测试(默认特性)
cargo test

# 运行所有测试(全部 confers 特性)
cargo test --all-features

# Lint
cargo clippy --all-features -- -D warnings

# 格式检查
cargo fmt --check

§行为准则

本项目遵循 Rust 行为准则。所有贡献者均需遵守。

§PR 流程

  1. 确保所有测试通过且 Clippy 无警告(cargo clippy --all-features -- -D warnings)。
  2. 为新功能添加测试。
  3. 保持 README 与 API 变更同步。

§📚 文档


§📋 更新日志

详见 CHANGELOG.md


§📄 许可证

MIT License, Copyright (c) 2026 Kirky.X

详见 LICENSE

Modules§

core
Core traits and types for module declaration.
i18n
国际化(i18n)支持 — Fluent FTL 消息翻译 + ICU4X 本地化格式化。
kit
Kit — the capability and configuration management center.
prelude
Re-exports of the most commonly used types and traits.

Macros§

impl_auto_builder
Implements AutoBuilder for a module type (sync counterpart to impl_async_auto_builder!).
impl_module_meta
Implements ModuleMeta for a module type (no dependencies).

Enums§

TraitKitError
Unified trait-kit error type.

Type Aliases§

TraitKitResult
Convenience Result alias for trait-kit operations.