什么是 HOCON ?
HOCON(Human-Optimized Config Object Notation,人性化配置对象表示法)是一种兼具人类可读性和机器可解析性的配置格式。它结合了 JSON 的简洁性与高级特性,如替换、包含和灵活的语法,非常适合现代应用程序中复杂的配置需求。HOCON 最初在 Java 生态系统中广受欢迎,现在通过像 hocon-rs 这样的库逐渐被其他编程语言采纳。
hocon-rs 简介
hocon-rs 是一个强大的 Rust 语言实现的 HOCON 配置库,为 Rust 生态系统带来了这一配置格式的全部功能。该库完全遵循 HOCON 规范,支持与 serde 的无缝集成,并提供替换、文件包含等高级功能。无论是开发小型命令行工具还是大型服务器应用,hocon-rs 都能提供可靠的配置管理方式。
开发这个库的初衷是我之前在将 Akka 移植到 Rust 时,发现 Rust 这边并没有特别好用的 HOCON 解析库,唯一的一个还停止维护了( Bug 还蛮多的),并且 Akka 中的配置多且复杂,使用其它配置格式非常痛苦。所以我决定自己写一个 HOCON 的解析库,后续引入到项目中。目前已经基本实现了所有功能,后续的方向是进一步优化,使其在解析大体量数据时减小和 serde_json 的耗时差距(HOCON 一般不作为数据交换格式,而是作为配置文件格式使用,所以数据量其实不大)。由于 HOCON 中包含一些高级特性例如合并、替换,简单值拼接以及引用其它配置文件等,因此解析逻辑要比其它配置解析器要复杂许多。
主要特性
1. 完全遵循 HOCON 规范
hocon-rs 支持 HOCON 规范的所有特性,包括:
- 注释:为配置添加人类可读的说明。
- 灵活语法:支持省略根大括号,使用=或:作为键值分隔符,允许省略非必要的逗号。
- 无引号和多行字符串:以自然方式编写配置,无需过多引号。
- 值拼接:无缝拼接字符串、数组和对象。
- 路径表达式和替换:在配置中动态引用值。
- 包含:支持从多个文件或格式(JSON、JavaProperties、HOCON)合并配置。
- 单位格式:支持人类可读的时长、周期和大小单位(如30s、1MB)。
2. 与 Serde 集成
通过 hocon-rs,可以直接将 HOCON 配置反序列化为 Rust 结构体,方便与依赖 serde 的 Rust 工作流程集成。
#[derive(Debug, Deserialize)]
struct Config {
app_name: String,
database: DatabaseConfig,
}
#[derive(Debug, Deserialize)]
struct DatabaseConfig {
host: String,
port: u32,
}
fn main() -> Result<(), hocon_rs::Error> {
let config: Config = hocon_rs::Config::parse_str(
r#"
app_name = "我的应用"
database {
host = "localhost"
port = 5432
}
"#,
None,
)?;
println!("{:?}", config);
Ok(())
}
3. 类路径支持
HOCON 中的“类路径”概念源自 Java ,hocon-rs 将其适配为 Rust ,允许定义用于搜索配置文件的目录根。默认情况下,它只在当前工作目录查找,但可以通过 ConfigOptions 自定义。
4. 安全解析与限制
为防止深层嵌套配置或复杂替换导致栈溢出,hocon-rs 设置了递归和替换深度限制(默认64层)。可通过 ConfigOptions 调整这些限制,确保安全性和灵活性。
5. 与 JSON 互操作
hocon-rs 基于 serde_json ,支持 hocon_rs::Value 与 serde_json::Value 之间的无缝转换,方便与其他基于 JSON 的工具和库集成。
快速上手
安装
在 Cargo.toml 中添加 hocon-rs :
[dependencies]
hocon-rs = "0.1"
加载配置文件
以下是一个示例配置文件(app.conf):
app-name = "我的应用"
database {
host = "localhost"
port = 5432
}
server {
port = 8080
timeout = 30s
}
在 Rust 中加载:
fn main() -> Result<(), hocon_rs::Error> {
let config: hocon_rs::Value = hocon_rs::Config::load("app.conf", None)?;
let host = config.get_by_path(["database", "host"]).unwrap();
println!("数据库主机: {}", host);
Ok(())
}
从字符串解析
也可以直接从字符串解析 HOCON 配置:
fn main() -> Result<(), hocon_rs::Error> {
let config: hocon_rs::Value = hocon_rs::Config::parse_str(
"{ app-name = 我的应用, version = 1.0 }",
None,
)?;
println!("配置: {}", config);
Ok(())
}
注意事项
项目状态
hocon-rs 仍在积极开发中,虽然大部分功能已实现,但公共API可能在未来版本中发生变化。请始终参考 docs.rs 上的最新文档。
替换
替换功能允许动态引用配置中的其他值,在解析的最后一步执行。然而,过于复杂或循环的替换可能导致 hocon-rs 解析错误,与 Java 实现略有不同。为确保清晰,建议避免复杂的替换模式。
无扩展名 include
当包含无扩展名的文件时,hocon-rs 会尝试解析 JSON 、JavaProperties 或 HOCON 格式并合并结果。可通过 ConfigOptions 自定义合并优先级。
为什么选择 hocon-rs?
hocon-rs 是 Rust 开发者管理配置的理想选择。它严格遵循 HOCON 规范,结合 Rust 的类型安全性和 serde 集成,适合各种规模的项目。无论是简单的键值对还是复杂的嵌套配置,hocon-rs 都能高效、可靠地处理。
结论
hocon-rs 将 HOCON 的灵活性和强大功能引入 Rust 生态系统,让开发者能够编写简洁、人类可读的配置,同时不失功能性。凭借其不断增长的功能集和积极的开发,hocon-rs 是你下一个 Rust 项目的理想选择。访问 GitHub 仓库了解更多详情,立即开始简化你的配置管理!