{"id":18956371,"url":"https://github.com/qedk/configparser-rs","last_synced_at":"2025-04-04T18:10:09.960Z","repository":{"id":43135770,"uuid":"271011578","full_name":"QEDK/configparser-rs","owner":"QEDK","description":"A simple configuration parsing utility with no dependencies built on Rust.","archived":false,"fork":false,"pushed_at":"2024-06-11T11:04:56.000Z","size":480,"stargazers_count":71,"open_issues_count":8,"forks_count":20,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-28T17:11:12.698Z","etag":null,"topics":["config","configparser","configuration","hacktoberfest","ini","ini-parser","parser","rust","settings"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/configparser","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/QEDK.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-LGPL","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-09T13:33:49.000Z","updated_at":"2025-03-10T09:27:18.000Z","dependencies_parsed_at":"2023-11-21T09:42:53.222Z","dependency_job_id":"80f7912b-d96f-4f6f-8a51-6f4b88a35ef8","html_url":"https://github.com/QEDK/configparser-rs","commit_stats":{"total_commits":229,"total_committers":7,"mean_commits":"32.714285714285715","dds":0.06113537117903933,"last_synced_commit":"1098ef7e6c08abaa3839a67e9830acfc032022f7"},"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QEDK%2Fconfigparser-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QEDK%2Fconfigparser-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QEDK%2Fconfigparser-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QEDK%2Fconfigparser-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/QEDK","download_url":"https://codeload.github.com/QEDK/configparser-rs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247226215,"owners_count":20904465,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["config","configparser","configuration","hacktoberfest","ini","ini-parser","parser","rust","settings"],"created_at":"2024-11-08T13:52:20.637Z","updated_at":"2025-04-04T18:10:09.940Z","avatar_url":"https://github.com/QEDK.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# configparser\n[![Build Status](https://github.com/QEDK/configparser-rs/actions/workflows/rust.yaml/badge.svg)](https://github.com/QEDK/configparser-rs/actions/workflows/rust.yaml) [![Crates.io](https://img.shields.io/crates/l/configparser?color=black)](LICENSE-MIT) [![Crates.io](https://img.shields.io/crates/v/configparser?color=black)](https://crates.io/crates/configparser) [![Released API docs](https://docs.rs/configparser/badge.svg)](https://docs.rs/configparser) [![Maintenance](https://img.shields.io/maintenance/yes/2024)](https://github.com/QEDK/configparser-rs)\n\nThis crate provides the `Ini` struct 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.\n\nThis is a simple configuration parsing utility with no dependencies built on Rust. It is inspired by Python's `configparser`.\n\nThe current release is stable and changes will take place at a slower pace. We'll be keeping semver in mind for future releases as well.\n\n## 🚀 Quick Start\n\nA basic `ini`-syntax file (we say ini-syntax files because the files don't need to be necessarily `*.ini`) looks like this:\n```INI\n[DEFAULT]\nkey1 = value1\npizzatime = yes\ncost = 9\n\n[topsecrets]\nnuclear launch codes = topsecret\n\n[github.com]\nUser = QEDK\n```\nEssentially, the syntax consists of sections, each of which can which contains keys with values. The `Ini` struct can read and write such values to\nstrings as well as files.\n\n### 🧰 Installation\nYou can install this easily via `cargo` by including it in your `Cargo.toml` file like:\n```TOML\n[dependencies]\nconfigparser = \"3.0.5\"\n```\n\n## ➕ Supported datatypes\n`configparser` does not guess the datatype of values in configuration files and stores everything as strings. However, some datatypes are so common\nthat 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()`,\n`getfloat()` and `getbool()`. The only bit of extra magic involved is that the `getbool()` function will treat boolean values case-insensitively (so\n`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.\n```rust\nuse configparser::ini::Ini;\n\nlet mut config = Ini::new();\nconfig.read(String::from(\n  \"[somesection]\n  someintvalue = 5\"));\nlet my_value = config.getint(\"somesection\", \"someintvalue\").unwrap().unwrap();\nassert_eq!(my_value, 5); // value accessible!\n\n//You can ofcourse just choose to parse the values yourself:\nlet my_string = String::from(\"1984\");\nlet my_int = my_string.parse::\u003ci32\u003e().unwrap();\n```\n\n## 📝 Supported `ini` file structure\nA 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.\nKey values can be omitted, in which case the key-value delimiter\nmay also be left out (but this is different from putting a delimiter, we'll\nexplain it later). You can use comment symbols (`;` and `#` to denote comments). This can be configured with the `set_comment_symbols()` method in the\nAPI. Keep in mind that key-value pairs or section headers cannot span multiple lines.\nOwing to how ini files usually are, this means that `[`, `]`, `=`, `:`, `;` and `#` are special symbols by default (this crate will allow you to use `]` sparingly).\n\nLet's take for example:\n```INI\n[section headers are case-insensitive by default]\n[   section headers are case-insensitive by default   ]\nare the section headers above same? = yes\nsectionheaders_and_keysarestored_in_lowercase? = yes\nkeys_are_also_case_insensitive = Values are case sensitive\nCase-sensitive_keys_and_sections = using a special constructor\nyou can also use colons : instead of the equal symbol\n;anything after a comment symbol is ignored\n#this is also a comment\nspaces in keys=allowed ;and everything before this is still valid!\nspaces in values=allowed as well\nspaces around the delimiter = also OK\n\n\n[All values are strings]\nvalues like this= 0000\nor this= 0.999\nare they treated as numbers? = no\nintegers, floats and booleans are held as= strings\n\n[value-less?]\na_valueless_key_has_None\nthis key has an empty string value has Some(\"\") =\n\n    [indented sections]\n        can_values_be_as_well = True\n        purpose = formatting for readability\n        is_this_same     =        yes\n            is_this_same=yes\n\n```\nAn 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\nor property key) is the one that remains in the `HashMap`.\nThe 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.\nKeep in mind that a section named \"default\" is also treated as sectionless so the output files remains consistent with no section header.\n\n## 🛠 Usage\nLet's take another simple `ini` file and talk about working with it:\n```INI\n[topsecret]\nKFC = the secret herb is orega-\n\n[values]\nUint = 31415\n```\nIf 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\nmanner and 3) we can use `getuint()` to parse the `Uint` value into an `u64`. Let's see that in action.\n\n```rust\nuse configparser::ini::{Ini, WriteOptions};\nuse std::error::Error;\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn Error\u003e\u003e {\n  let mut config = Ini::new();\n\n  // You can easily load a file to get a clone of the map:\n  let map = config.load(\"tests/test.ini\")?;\n  println!(\"{:?}\", map);\n  // You can also safely not store the reference and access it later with get_map_ref() or get a clone with get_map()\n\n  // If you want to access the value, then you can simply do:\n  let val = config.get(\"TOPSECRET\", \"KFC\").unwrap();\n  // Notice how get() can access indexes case-insensitively.\n\n  assert_eq!(val, \"the secret herb is orega-\"); // value accessible!\n\n  // What if you want remove KFC's secret recipe? Just use set():\n  config.set(\"topsecret\", \"kfc\", None);\n\n  assert_eq!(config.get(\"TOPSECRET\", \"KFC\"), None); // as expected!\n\n  // What if you want to get an unsigned integer?\n  let my_number = config.getuint(\"values\", \"Uint\")?.unwrap();\n  assert_eq!(my_number, 31415); // and we got it!\n  // The Ini struct provides more getters for primitive datatypes.\n\n  // You can also access it like a normal hashmap:\n  let innermap = map[\"topsecret\"].clone();\n  // Remember that all indexes are stored in lowercase!\n\n  // 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:\n  config.write(\"output.ini\");\n\n  // You can write the currently stored configuration with different spacing to a file with the `pretty_write` method:\n  let write_options = WriteOptions::new_with_params(true, 2, 1);\n  // or you can use the default configuration as `WriteOptions::new()`\n  config.pretty_write(\"pretty_output.ini\", \u0026write_options);\n\n  // If you want to simply mutate the stored hashmap, you can use get_mut_map()\n  let map = config.get_mut_map();\n  // You can then use normal HashMap functions on this map at your convenience.\n  // Remember that functions which rely on standard formatting might stop working\n  // if it's mutated differently.\n\n  // If you want a case-sensitive map, just do:\n  let mut config = Ini::new_cs();\n  // This automatically changes the behaviour of every function and parses the file as case-sensitive.\n\n  Ok(())\n}\n```\nThe `Ini` struct offers great support for type conversion and type setting safely, as well as map accesses. See the API for more verbose documentation.\n\n## 📖Features\n\n - *indexmap*: Activating the `indexmap` feature allows using [indexmap](https://crates.io/crates/indexmap) in place\n  of `HashMap` to store the sections and keys. This ensures that insertion order is preserved when iterating on or\n  serializing the Ini object.\n  Due to the nature of indexmap, it offers mostly similar performance to stdlib HashMaps but with\n  [slower lookup times](https://github.com/bluss/indexmap#performance).\n\nYou can activate it by adding it as a feature like this:\n```TOML\n[dependencies]\nconfigparser = { version = \"3.1.0\", features = [\"indexmap\"] }\n```\n\n - *tokio*: Activating the `tokio` feature adds asynchronous functions for reading from (`load_async()`) and\n   writing to (`write_async()`) files using [tokio](https://crates.io/crates/tokio).\n\nYou can activate it by adding it as a feature like this:\n```TOML\n[dependencies]\nconfigparser = { version = \"3.1.0\", features = [\"tokio\"] }\n```\n\n## 📜 License\n\nLicensed under either of\n\n * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n * Lesser General Public license v3.0 or later ([LICENSE-LGPL](LICENSE-LGPL) or https://www.gnu.org/licenses/lgpl-3.0.html)\n\nat your option.\n\n### ✏ Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the LGPL-3.0 license, shall be dual licensed as above, without any\nadditional terms or conditions.\n\n## 🆕 Changelog\n\nOld changelogs are in [CHANGELOG.md](CHANGELOG.md).\n- 3.0.0\n  - 😅 **BREAKING** `IniDefault` is now a non-exhaustive struct, this will make future upgrades easier and non-breaking in nature. This change might also have a few implications in updating your existing codebase, please read the [official docs](https://doc.rust-lang.org/reference/attributes/type_system.html#the-non_exhaustive-attribute) for more guidance.\n  - `IniDefault` is now internally used for generating defaults, reducing crate size.\n  - 🚀 There is now a new optional `indexmap` feature that preserves insertion order of your loaded configurations.\n- 3.0.1\n  - Uses `CRLF` line endings for Windows files.\n  - Bumps crate to 2021 edition.\n  - Adds features to CI pipeline.\n- 3.0.2\n  - Adds support for multi-line key-value pairs.\n  - Adds `async-std` feature for asynchronous file operations.\n  - Some performance optimizations.\n- 3.0.3 \n  - Add default empty line on empty strings.\n  - Feature to append to existing `Ini` objects.\n  - Minor lint fixes.\n- 3.0.4\n  - Adds pretty printing functionality\n  - Replaces `async-std` with `tokio` as the available async runtime\n  - *The `async-std` feature will be deprecated in a future release*\n- 3.1.0 (**STABLE**)\n  - `async-std` has been deprecated\n  - Fixes a bug where multiline values did not preserve newlines\n  - Fixes a bug where empty sections were removed\n  - Adds a feature to support inline comments\n\n### 🔜 Future plans\n\n- Support for appending sections, coercing them as well.\n- Benchmarking against similar packages.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqedk%2Fconfigparser-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqedk%2Fconfigparser-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqedk%2Fconfigparser-rs/lists"}