knife-util 0.1.0

Utility library for knife project
Documentation

knife-util

Crates.io Documentation License

一个为 knife 项目提供通用工具和功能的 Rust 库。

🚀 功能特性

📦 核心模块

  • 🔧 错误处理: 统一的错误类型和处理机制,支持错误链和上下文信息
  • 🔄 JSON合并: 深度合并JSON数据,支持类型转换和枚举处理
  • 📁 路径工具: 自动检测工作目录和项目路径,支持开发/生产环境
  • 📄 TOML工具: TOML与JSON之间的双向转换功能

✨ 主要特性

  • 🛡️ 类型安全: 所有操作都是类型安全的,编译时检查
  • 🔄 深度合并: 支持嵌套对象的递归合并
  • 🎯 智能转换: 自动处理数字、布尔值、字符串之间的类型转换
  • 📊 枚举支持: 支持自定义枚举类型的转换
  • 🏗️ 环境感知: 自动识别开发和生产环境
  • 📚 完整文档: 提供详细的API文档和使用示例

📦 安装

Cargo.toml 中添加依赖:

[dependencies]

knife-util = "0.1.0"

🚀 快速开始

JSON 合并

use knife_util::{AppError, merge_json};
use serde_json::json;

fn main() -> Result<(), AppError> {
    let target = json!({"user": {"name": "Alice"}});
    let source = json!({"user": {"email": "alice@example.com"}});
    
    // 深度合并JSON数据
    let merged = merge_json(&target, &source)?;
    println!("合并结果: {}", serde_json::to_string_pretty(&merged).unwrap());
    Ok(())
}

路径工具

use knife_util::{AppError, get_work_dir, is_dev_mode};

fn main() -> Result<(), AppError> {
    // 获取工作目录
    let work_dir = get_work_dir()?;
    println!("工作目录: {:?}", work_dir);
    
    // 检查是否为开发模式
    if is_dev_mode() {
        println!("当前在开发模式中");
    } else {
        println!("当前在生产模式中");
    }
    Ok(())
}

TOML 转换

use knife_util::{AppError, toml_to_json, json_to_toml};
use serde_json::json;

fn main() -> Result<(), AppError> {
    // TOML 到 JSON 转换
    let toml_str = r#"
        title = "Example"
        [database]
        host = "localhost"
        port = 5432
    "#;
    let json_value = toml_to_json(toml_str)?;
    println!("TOML -> JSON: {}", serde_json::to_string_pretty(&json_value).unwrap());
    
    // JSON 到 TOML 转换
    let json_data = json!({
        "app": {"name": "MyApp", "version": "1.0.0"}
    });
    let toml_result = json_to_toml(&json_data)?;
    println!("JSON -> TOML:\n{}", toml_result);
    Ok(())
}

📚 API 文档

错误处理

AppError

统一的错误类型,支持错误链和上下文信息:

use knife_util::AppError;

// 创建基本错误
let error = AppError::new("USER_ERROR", "用户不存在");

// 添加上下文信息
let error = error.with_attribute("user_id", 123);

// 从其他错误类型创建
let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "File not found");
let app_error = AppError::from_error("FILE_ERROR", "文件操作失败", io_error);

JSON 合并

merge_json

深度合并两个JSON值:

use knife_util::merge_json;
use serde_json::json;

let target = json!({"user": {"name": "Alice", "age": 30}});
let source = json!({"user": {"email": "alice@example.com"}, "settings": {"theme": "dark"}});

let merged = merge_json(&target, &source)?;
// 结果: {"user": {"name": "Alice", "age": 30, "email": "alice@example.com"}, "settings": {"theme": "dark"}}

类型转换

支持基本类型之间的转换:

use knife_util::merge::try_type_conversion;
use serde_json::json;

// 数字 ↔ 字符串
let result = try_type_conversion(&json!(42), &json!("123"))?;
assert_eq!(result, json!(123));

// 布尔值 ↔ 字符串
let result = try_type_conversion(&json!(true), &json!("yes"))?;
assert_eq!(result, json!(true));

枚举转换

支持自定义枚举类型的转换:

use knife_util::merge::try_enum_conversion;
use serde_json::json;

#[derive(Debug, Clone, PartialEq)]
enum Status {
    Active,
    Inactive,
}

impl std::str::FromStr for Status {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s.to_lowercase().as_str() {
            "active" | "running" => Ok(Status::Active),
            "inactive" | "stopped" => Ok(Status::Inactive),
            _ => Err(format!("Invalid status: {}", s))
        }
    }
}

impl std::fmt::Display for Status {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            Status::Active => write!(f, "ACTIVE"),
            Status::Inactive => write!(f, "INACTIVE"),
        }
    }
}

let result = try_enum_conversion::<Status>(&json!("ACTIVE"), &json!("running"))?;
assert_eq!(result, json!("ACTIVE"));

路径工具

get_work_dir

自动检测工作目录:

use knife_util::get_work_dir;

let work_dir = get_work_dir()?;
// 开发环境: /path/to/project/workspace
// 生产环境: /path/to/executable/directory

is_dev_mode

检查是否为开发模式:

use knife_util::is_dev_mode;

if is_dev_mode() {
    println!("开发模式");
} else {
    println!("生产模式");
}

build_work_path

构建工作路径:

use knife_util::build_work_path;

let config_path = build_work_path("config/app.toml")?;
// 结果: /path/to/workspace/config/app.toml

TOML 工具

toml_to_json

将TOML字符串转换为JSON:

use knife_util::toml_to_json;

let toml_str = r#"
    title = "Example"
    [database]
    host = "localhost"
    port = 5432
"#;

let json_value = toml_to_json(toml_str)?;

json_to_toml

将JSON值转换为TOML字符串:

use knife_util::json_to_toml;
use serde_json::json;

let json_data = json!({
    "app": {"name": "MyApp", "version": "1.0.0"},
    "database": {"host": "localhost", "port": 5432}
});

let toml_str = json_to_toml(&json_data)?;

toml_file_to_json

从文件读取TOML并转换为JSON:

use knife_util::toml_file_to_json;

let json_value = toml_file_to_json("config.toml")?;

🛠️ 开发

构建

cargo build

测试

cargo test

文档

cargo doc --open

代码覆盖率

cargo tarpaulin --out stdout

📋 依赖

  • serde - 序列化框架
  • serde_json - JSON支持
  • anyhow - 错误处理
  • toml - TOML解析
  • tracing-subscriber - 日志支持

🤝 贡献

欢迎贡献代码!请遵循以下步骤:

  1. Fork 项目
  2. 创建特性分支 (git checkout -b feature/amazing-feature)
  3. 提交更改 (git commit -m 'Add some amazing feature')
  4. 推送到分支 (git push origin feature/amazing-feature)
  5. 打开 Pull Request

📄 许可证

本项目采用 Apache 2.0 许可证 - 查看 LICENSE 文件了解详情。

🔗 相关链接

📊 项目状态

  • ✅ 错误处理模块
  • ✅ JSON合并功能
  • ✅ 路径工具
  • ✅ TOML转换
  • ✅ 完整测试覆盖
  • ✅ 文档完善

knife-util - 让 Rust 开发更简单! 🦀