#ini #config-file #parser #configuration #settings

configparser

一个无依赖项的简单配置解析工具,允许您解析 INI 和 ini 风格的语法。您可以使用它来编写可以被最终用户轻松定制的 Rust 程序。

34 个版本 (10 个稳定版)

3.1.0 2024年6月11日
3.0.4 2024年1月2日
3.0.3 2023年11月16日
3.0.2 2022年9月11日
0.13.2 2020年7月20日

#15解析器实现

Download history 29380/week @ 2024-05-03 23500/week @ 2024-05-10 20954/week @ 2024-05-17 21581/week @ 2024-05-24 26277/week @ 2024-05-31 21078/week @ 2024-06-07 21866/week @ 2024-06-14 22612/week @ 2024-06-21 19309/week @ 2024-06-28 23906/week @ 2024-07-05 24720/week @ 2024-07-12 28902/week @ 2024-07-19 122682/week @ 2024-07-26 98155/week @ 2024-08-02 120281/week @ 2024-08-09 140241/week @ 2024-08-16

每月下载量 489,744
95 软件包中使用 95 (直接使用)

MIT OR LGPL-3.0-or-later

73KB
675

configparser

Build Status Crates.io Crates.io Released API docs Maintenance

此软件包提供了 Ini 结构体,它实现了一种基本的配置语言,提供类似于 Windows 的 ini 文件中找到的结构。您可以使用它来编写可以被最终用户轻松定制的 Rust 程序。

这是一个基于 Rust 的简单配置解析工具,没有依赖项,灵感来源于 Python 的 configparser

当前版本是稳定的,变化将缓慢进行。对于未来的版本,我们也将考虑 semver。

🚀 快速入门

一个基本的 ini 语法文件(我们说 ini 语法文件,因为文件不一定是 *.ini)看起来像这样

[DEFAULT]
key1 = value1
pizzatime = yes
cost = 9

[topsecrets]
nuclear launch codes = topsecret

[github.com]
User = QEDK

基本上,语法由部分组成,每个部分可以包含具有值的键。`Ini` 结构体可以读取和将这些值写入字符串以及文件。

🧰 安装

您可以通过在您的 Cargo.toml 文件中包含它来通过 cargo 简单地安装它,如下所示

[dependencies]
configparser = "3.0.5"

➕ 支持的数据类型

configparser 无法猜测配置文件中值的数据类型,并将所有内容都存储为字符串。然而,一些数据类型非常常见,因此可以安全地假设某些值需要以其他类型进行解析。为此,Ini 结构体提供了易于使用的函数,如 getint()getuint()getfloat()getbool()。唯一需要额外注意的魔法是,getbool() 函数将不区分大小写地处理布尔值(因此 trueTrue 以及 TRUE 相同)。此外,该包还提供了一个更强大的 getboolcoerce() 函数,它可以解析更多值(如 Tyes0,均不区分大小写),该函数的文档将提供详细信息。

use configparser::ini::Ini;

let mut config = Ini::new();
config.read(String::from(
  "[somesection]
  someintvalue = 5"));
let my_value = config.getint("somesection", "someintvalue").unwrap().unwrap();
assert_eq!(my_value, 5); // value accessible!

//You can ofcourse just choose to parse the values yourself:
let my_string = String::from("1984");
let my_int = my_string.parse::<i32>().unwrap();

📝 支持的 ini 文件结构

配置文件可以由部分组成,每个部分以一个 [section-name] 标题开始,后跟由分隔符(=:)分隔的键值条目。默认情况下,部分名称和键名称不区分大小写。可以使用 Ini::new_cs() 构造函数启用大小写敏感。所有键、值和部分名称的前导和尾随空白都将被删除。键值可以省略,在这种情况下,键值分隔符也可以省略(但与放置分隔符不同,我们稍后将其解释)。您可以使用注释符号(;#)来表示注释。这可以通过 API 中的 set_comment_symbols() 方法进行配置。请注意,键值对或部分标题不能跨越多行。由于 ini 文件通常如此,这意味着 []=:;# 是默认的特殊符号(此包将允许您少量使用 ])。

让我们以一个例子来解释

[section headers are case-insensitive by default]
[   section headers are case-insensitive by default   ]
are the section headers above same? = yes
sectionheaders_and_keysarestored_in_lowercase? = yes
keys_are_also_case_insensitive = Values are case sensitive
Case-sensitive_keys_and_sections = using a special constructor
you can also use colons : instead of the equal symbol
;anything after a comment symbol is ignored
#this is also a comment
spaces in keys=allowed ;and everything before this is still valid!
spaces in values=allowed as well
spaces around the delimiter = also OK


[All values are strings]
values like this= 0000
or this= 0.999
are they treated as numbers? = no
integers, floats and booleans are held as= strings

[value-less?]
a_valueless_key_has_None
this key has an empty string value has Some("") =

    [indented sections]
        can_values_be_as_well = True
        purpose = formatting for readability
        is_this_same     =        yes
            is_this_same=yes

需要注意的是,具有相同键的值将被更新,这意味着最后插入的键(无论是部分标题还是属性键)将保留在 HashMap 中。API 做的唯一一点魔法是将无部分的属性放入名为 "default" 的部分中。您可以通过 API 配置此变量。请注意,名为 "default" 的部分也被视为无部分,以确保输出文件的一致性,没有部分标题。

🛠 使用方法

让我们再来看一个简单的 ini 文件,并讨论如何使用它

[topsecret]
KFC = the secret herb is orega-

[values]
Uint = 31415

如果您仔细阅读上面的部分,您会知道:1) 所有键都存储为小写,2) get()可以实现不区分大小写的访问,3) 我们可以使用getuint()Uint值解析为u64。让我们看看实际效果。

use configparser::ini::{Ini, WriteOptions};
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
  let mut config = Ini::new();

  // You can easily load a file to get a clone of the map:
  let map = config.load("tests/test.ini")?;
  println!("{:?}", map);
  // You can also safely not store the reference and access it later with get_map_ref() or get a clone with get_map()

  // If you want to access the value, then you can simply do:
  let val = config.get("TOPSECRET", "KFC").unwrap();
  // Notice how get() can access indexes case-insensitively.

  assert_eq!(val, "the secret herb is orega-"); // value accessible!

  // What if you want remove KFC's secret recipe? Just use set():
  config.set("topsecret", "kfc", None);

  assert_eq!(config.get("TOPSECRET", "KFC"), None); // as expected!

  // What if you want to get an unsigned integer?
  let my_number = config.getuint("values", "Uint")?.unwrap();
  assert_eq!(my_number, 31415); // and we got it!
  // The Ini struct provides more getters for primitive datatypes.

  // You can also access it like a normal hashmap:
  let innermap = map["topsecret"].clone();
  // Remember that all indexes are stored in lowercase!

  // You can easily write the currently stored configuration to a file with the `write` method. This creates a compact format with as little spacing as possible:
  config.write("output.ini");

  // You can write the currently stored configuration with different spacing to a file with the `pretty_write` method:
  let write_options = WriteOptions::new_with_params(true, 2, 1);
  // or you can use the default configuration as `WriteOptions::new()`
  config.pretty_write("pretty_output.ini", &write_options);

  // If you want to simply mutate the stored hashmap, you can use get_mut_map()
  let map = config.get_mut_map();
  // You can then use normal HashMap functions on this map at your convenience.
  // Remember that functions which rely on standard formatting might stop working
  // if it's mutated differently.

  // If you want a case-sensitive map, just do:
  let mut config = Ini::new_cs();
  // This automatically changes the behaviour of every function and parses the file as case-sensitive.

  Ok(())
}

Ini结构体为类型转换和类型设置提供了强大的支持,以及映射访问。请参阅API以获取更多详细文档。

📖特性

  • indexmap:激活indexmap特性,允许使用indexmap替代HashMap来存储节和键。这确保了在迭代或序列化Ini对象时插入顺序得到保留。由于indexmap的性质,它提供的性能与stdlib HashMaps相似,但查找时间较慢

您可以通过将其添加为特性来激活它

[dependencies]
configparser = { version = "3.1.0", features = ["indexmap"] }
  • tokio:激活tokio特性,添加了使用tokio进行文件读写(load_async()write_async())的异步函数。

您可以通过将其添加为特性来激活它

[dependencies]
configparser = { version = "3.1.0", features = ["tokio"] }

📜 许可证

根据您的要求,许可协议为以下之一

✏ 贡献

除非您明确声明,否则您提交给工作的任何贡献,根据LGPL-3.0许可证定义,将按上述方式双重许可,没有额外的条款或条件。

🆕 更新日志

旧更新日志在CHANGELOG.md

  • 3.0.0
    • 😅 重大变更 IniDefault现在是一个不完整的结构体,这将使未来的升级更容易,且具有非破坏性。此更改也可能对更新现有的代码库产生一些影响,请参阅官方文档以获取更多指导。
    • IniDefault现在内部用于生成默认值,减少crate大小。
    • 🚀 现在有一个新的可选的indexmap特性,它保留了加载配置的插入顺序。
  • 3.0.1
    • Windows文件使用CRLF换行符。
    • 将crate升级到2021版。
    • 添加到CI管道的功能。
  • 3.0.2
    • 添加对多行键值对的支持。
    • 添加异步文件操作async-std功能。
    • 一些性能优化。
  • 3.0.3
    • 在空字符串上添加默认空行。
    • 将现有Ini对象附加到功能。
    • 一些小的lint修复。
  • 3.0.4
    • 添加了漂亮的打印功能
    • async-std替换为可用的异步运行时tokio
    • 在未来版本中将弃用async-std功能
  • 3.1.0(稳定
    • async-std 已弃用
    • 修复了一个问题,多行值不会保留换行符
    • 修复了一个问题,空节被移除
    • 增加了一个支持内联注释的功能

🔜 未来计划

  • 支持追加章节,并强制转换它们。
  • 与类似包进行基准测试。

依赖项

~0–1.3MB
~22K SLoC