configparser
configparser is a configuration parsing utility with zero dependencies built in Rust. It is inspired by the similarly named Python configparser library.
This crate provides an Ini struct which implements a succinct configuration language and provides a structure similar to whatโs found in ini files (similar to .env files). You can use this to write Rust programs which can be configured by end users.
We use semantic versioning, so breaking changes will only be introduced in major versions. The crate is stable and has been used in production for a long time.
๐ Quick Start
A basic ini-format file looks like this:
[DEFAULT]
key1 = value1
pizzatime = yes
cost = 9
[topsecrets]
nuclear launch codes = topsecret
[github.com]
User = QEDK
Essentially, the syntax consists of sections, each of which can which contains keys with values. The Ini struct can read and write such values to
strings as well as files.
๐งฐ Installation
You can install this easily via cargo by including it in your Cargo.toml file like:
[]
= "3.2.0"
โ Supported datatypes
configparser does not guess the datatype of values in configuration files and stores everything as strings. However, some datatypes are so common
that it's a safe bet that some values need to be parsed in other types. For this, the Ini struct provides easy functions like getint(), getuint(),
getfloat() and getbool(). The only bit of extra magic involved is that the getbool() function will treat boolean values case-insensitively (so
true is the same as True just like TRUE). The crate also provides a stronger getboolcoerce() function that parses more values (such as T, yes and 0, all case-insensitively), the function's documentation will give you the exact details.
use Ini;
let mut config = new;
config.read;
let my_value = config.getint.unwrap.unwrap;
assert_eq!; // value accessible!
//You can ofcourse just choose to parse the values yourself:
let my_string = Stringfrom;
let my_int = my_string..unwrap;
๐ Supported ini file structure
A configuration file can consist of sections, each led by a [section-name] header, followed by key-value entries separated by a delimiter (= and :). By default, section names and key names are case-insensitive. Case-sensitivity can be enabled using the Ini::new_cs() constructor. All leading and trailing whitespace is removed from stored keys, values and section names.
Key values can be omitted, in which case the key-value delimiter
may also be left out (but this is different from putting a delimiter, we'll
explain it later). You can use comment symbols (; and # to denote comments). This can be configured with the set_comment_symbols() method in the
API. Keep in mind that key-value pairs or section headers cannot span multiple lines.
Owing to how ini files usually are, this means that [, ], =, :, ; and # are special symbols by default (this crate will allow you to use ] sparingly).
Let's take for example:
[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
An important thing to note is that values with the same keys will get updated, this means that the last inserted key (whether that's a section header
or property key) is the one that remains in the HashMap.
The only bit of magic the API does is the section-less properties are put in a section called "default". You can configure this variable via the API.
Keep in mind that a section named "default" is also treated as sectionless so the output files remains consistent with no section header.
๐ Usage
Let's take another simple ini file and talk about working with it:
[topsecret]
KFC = the secret herb is orega-
[values]
Uint = 31415
If you read the above sections carefully, you'll know that 1) all the keys are stored in lowercase, 2) get() can make access in a case-insensitive
manner and 3) we can use getuint() to parse the Uint value into an u64. Let's see that in action.
use ;
use Error;
The Ini struct offers great support for type conversion and type setting safely, as well as map accesses. See the API for more verbose documentation.
๐Features
- indexmap: Activating the
indexmapfeature allows using indexmap in place ofHashMapto store the sections and keys. This ensures that insertion order is preserved when iterating on or serializing the Ini object. Due to the nature of indexmap, it offers mostly similar performance to stdlib HashMaps but with slower lookup times.
You can activate it by adding it as a feature like this:
[]
= { = "3.2.0", = ["indexmap"] }
- tokio: Activating the
tokiofeature adds asynchronous functions for reading from (load_async()) and writing to (write_async()) files using tokio.
You can activate it by adding it as a feature like this:
[]
= { = "3.2.0", = ["tokio"] }
Override Options
You can change the default configuration options like this. See the API for more verbose documentation.
let mut parser_options = default;
parser_options.multiline = true;
parser_options.enable_inline_comments = false;
let mut config = new_from_defaults;
๐ License
Licensed under either of
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
- Lesser General Public license v3.0 or later (LICENSE-LGPL or https://www.gnu.org/licenses/lgpl-3.0.html)
at your option.
โ Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the LGPL-3.0 license, shall be dual licensed as above, without any additional terms or conditions.