Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/qedk/ini-rs
A simple macro utility built on top of configparser with no other dependencies built on Rust.
https://github.com/qedk/ini-rs
configuration ini macro parser rust settings
Last synced: 3 months ago
JSON representation
A simple macro utility built on top of configparser with no other dependencies built on Rust.
- Host: GitHub
- URL: https://github.com/qedk/ini-rs
- Owner: QEDK
- License: lgpl-3.0
- Created: 2020-06-16T06:16:02.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2021-09-25T17:57:53.000Z (over 3 years ago)
- Last Synced: 2024-10-05T21:05:00.165Z (4 months ago)
- Topics: configuration, ini, macro, parser, rust, settings
- Language: Rust
- Homepage:
- Size: 69.3 KB
- Stars: 8
- Watchers: 3
- Forks: 2
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE-LGPL
Awesome Lists containing this project
README
# ini
[![Build Status](https://travis-ci.com/mexili/ini-rs.svg?branch=master)](https://travis-ci.com/mexili/ini-rs) [![Crates.io](https://img.shields.io/crates/l/ini?color=black)](LICENSE-MIT) [![Crates.io](https://img.shields.io/crates/v/ini?color=black)](https://crates.io/crates/ini) [![Released API docs](https://docs.rs/ini/badge.svg)](https://docs.rs/ini) [![Maintenance](https://img.shields.io/maintenance/yes/2020)](https://github.com/mexili/ini-rs)This crate provides the `ini!` macro which implements a basic configuration language which provides a structure similar to what’s found in Windows' `ini` files. You can use this to write Rust programs which can be customized by end users easily.
This is a simple macro utility built on top of `configparser` with no other dependencies built on Rust. For more advanced functions, you should use the [configparser](https://crates.io/crates/configparser) crate.
## Quick Start
A basic `ini`-syntax file (we say ini-syntax files because the files don't need to be necessarily `*.ini`) looks like this:
```INI
[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.### Installation
You can install this easily via `cargo` by including it in your `Cargo.toml` file like:
```TOML
[dependencies]
ini = "1.3.0"
```### The `ini!` macro
The `ini!` macro allows you to simply get a hashmap of type `HashMap>>` for a list of files.
It is planned to provide shell expansion and file-writing in the future:
```rust
#[macro_use]
extern crate ini;fn main() {
let map = ini!("...path/to/file");
// Proceed to use normal HashMap functions on the map:
let val = map["section"]["key"].clone().unwrap();// To load multiple files, just do:
let (map1, map2, map3) = ini!("path/to/file1", "path/to/file2", "path/to/file3");
// Each map is a cloned hashmap with no relation to other ones
}
```
If loading a file fails or the parser is unable to parse the file, the code will `panic` with an appropriate error. In case, you want to handle this
gracefully, it's recommended you use the `safe` metavariable instead. This will make sure your code does not panic and instead exists as a
`Result` type and let you deal with errors gracefully.
```rust
let map = ini!(safe "...path/to/file");
// Proceed to use normal HashMap functions on the map:
let val = map.unwrap()["section"]["key"].clone().unwrap();
// Note the extra unwrap here, which is required because our HashMap is inside a Result type.
```### The `inistr!` macro
The `inistr!` macro allows you to simply get a hashmap of type `HashMap>>` for a list of strings.
```rust
#[macro_use]
extern crate ini;fn main() {
let configstring = "[section]
key = value
top = secret";
let map = inistr!(configstring);
// Proceed to use normal HashMap functions on the map:
let val = map["section"]["top"].clone().unwrap();
// The type of the map is HashMap>>
assert_eq!(val, "secret"); // value accessible!// To load multiple string, just do:
let (map1, map2, map3) = inistr!(&String::from(configstring), configstring, "[section]
key = value
top = secret");
// Each map is a cloned hashmap with no relation to other ones
}
```
If loading a file fails or the parser is unable to parse the file, the code will `panic` with an appropriate error. In case, you want to handle this
gracefully, it's recommended you use the `safe` metavariable instead. This will make sure your code does not panic and instead exists as a
`Result` type and let you deal with errors gracefully.
```rust
let map = inistr!(safe strvariable_or_strliteral);
// Proceed to use normal HashMap functions on the map:
let val = map.unwrap()["section"]["key"].clone().unwrap();
// Note the extra unwrap here, which is required because our HashMap is inside a Result type.
```## Supported datatypes
`configparser` does not guess the datatype of values in configuration files and stores everything as strings, same applies to `ini`. If you need getters that parse the values for you, you might want to use the `configparser` crate instead. You can ofcourse just choose to parse the string values yourself.
```rust
let my_string = map["section"]["key"].clone().unwrap();
let my_int = my_string.parse::().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 `=`. By default, section names and key names are case-insensitive. 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). 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 (this crate will allow you to use `]` sparingly).Let's take for example:
```INI
[section headers are case-insensitive]
[ section headers are case-insensitive ]
are the section headers above same? = yes
sectionheaders_and_keysarestored_in_lowercase? = yes
keys_are_also_case_insensitive = Values are case sensitive
;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".## License
Licensed under either of
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
* Lesser General Public license v3.0 or later ([LICENSE-LGPL](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.