#ini #no-std #configuration #parser

no-std ini-roundtrip

Fast format preserving (round-tripping) INI-parser

4 releases

0.1.3 Feb 12, 2024
0.1.2 Jun 19, 2023
0.1.1 Apr 20, 2023
0.1.0 Mar 20, 2023

#664 in Configuration

Download history 76/week @ 2023-11-09 156/week @ 2023-11-16 225/week @ 2023-11-23 580/week @ 2023-11-30 122/week @ 2023-12-07 381/week @ 2023-12-14 350/week @ 2023-12-21 437/week @ 2023-12-28 428/week @ 2024-01-04 337/week @ 2024-01-11 295/week @ 2024-01-18 699/week @ 2024-01-25 305/week @ 2024-02-01 649/week @ 2024-02-08 366/week @ 2024-02-15 355/week @ 2024-02-22

1,677 downloads per month
Used in 2 crates (via ini-merge)

MIT license

697 lines

Fast format preserving (round-tripping) INI-parser

[ crates.io ] [ lib.rs ] [ docs.rs ]

ini-roundtrip is a fast format preserving (round-tripping) streaming INI parser that attempts to work on arbitrary INI files.

The code is inspired by and heavily based on ini_core.


Current minimum supported Rust version is 1.70.0. This may be updated as needed. MSRV bump is not considered a semver breaking change.


Format preserving Ini streaming parser

Simple INI parser with the following features:


  • Format-preserving (you can write out again and get identical result)
  • Fast!
  • Streaming
  • no_std support


  • The Display trait on [Item] does not preserve formatting, if this is something you want, make sure to use the raw attributes to extract the raw line instead.
  • Newlines are not saved. It is up to the caller to keep track of the type of newline in use. Mixed newline (e.g. a mix of CR, CRLF and LF) is supported on loading, but not on saving.


use ini_roundtrip as ini;

let document = "\
;this is a comment
Key = Value  ";

let elements = [
ini::Item::Section{name: "SECTION", raw: "[SECTION]"},
ini::Item::Comment{raw: ";this is a comment"},
ini::Item::Property{key: "Key", val: Some("Value"), raw: "Key = Value  "},

for (index, item) in ini::Parser::new(document).enumerate() {
assert_eq!(item, elements[index]);

The SectionEnd pseudo element is returned before a new section and at the end of the document. This helps processing sections after their properties finished parsing.

The parser is very much line-based, it will continue no matter what and return nonsense as an item:

use ini_roundtrip as ini;

let document = "\

let elements = [
ini::Item::Property{key: "nonsense", val: None, raw: "nonsense"},

for (index, item) in ini::Parser::new(document).enumerate() {
assert_eq!(item, elements[index]);

Lines starting with [ but contain either no closing ] or a closing ] not followed by a newline are returned as Item::Error. Lines missing a = are returned as Item::Property with None value. See below for more details.


INI is not a well specified format, this parser tries to make as little assumptions as possible but it does make decisions.

  • Newline is either "\r\n", "\n" or "\r". It can be mixed in a single document but this is not recommended.
  • Section header is "[" section "]" newline. section can be anything except contain newlines.
  • Property is key "=" value newline. key and value can be anything except contain newlines.
  • Comment is the raw line for lines starting with ; or #
  • Blank is just newline.

Padding whitespace is always trimmed, but the raw line is always stored as well.

No further processing of the input is done, eg. if escape sequences are necessary they must be processed by the caller.