kv-parser 0.3.0

A simple parser of key-value-files as hash maps
Documentation
# Kv Parser — parses whitespace-separated key-value lines from strings or files into a hash map

A Rust library for parsing simple key-value text into `HashMap<Box<str>, Box<str>>`.

## Format

Each non-empty line contains a key-value pair separated by whitespace:

- Keys and values are separated by the **first** whitespace character on each line
- Keys cannot contain whitespace
- Values can contain any characters including whitespace (leading/trailing whitespace is trimmed)
- Empty lines and lines without whitespace are ignored
- Keys must be unique (duplicate keys result in an error)

## Usage

Add to your `Cargo.toml`:

```toml
[dependencies]
kv-parser = "0.3.0"
```

`text_to_key_value_map` parses a string, `file_to_key_value_map` reads a file and parses its contents:

```rust
use std::path::Path;

use kv_parser::{Error, file_to_key_value_map, text_to_key_value_map};

fn main() -> Result<(), Error> {
    let defaults = text_to_key_value_map("current-level tutorial\nstart-point 0")?;

    let path = Path::new("savedata.sav");
    let save_data = file_to_key_value_map(path)?;

    if let Some(level) = save_data.get("current-level").or(defaults.get("current-level")) {
        println!("Current level: {level}");
    }

    Ok(())
}
```

## Error Handling

Both functions return `Result<HashMap<Box<str>, Box<str>>, Error>` where `Error` can be:

- `Error::OpeningFile` - Failed to open the file
- `Error::ReadingFile` - I/O error while reading the file
- `Error::MultipleKeys(key)` - Duplicate key found

`text_to_key_value_map` takes a string that is already in memory, so it only ever returns `Error::MultipleKeys`.

## Example

Given a file `savedata.sav`:
```
current-level vulcano
start-point 3
player-upgrades super-jump climbing lava-suit bombs
```

The parsed result:

```rust
use std::{collections::HashMap, path::Path};

use kv_parser::file_to_key_value_map;

let mut expected = HashMap::new();
expected.insert("current-level".into(), "vulcano".into());
expected.insert("start-point".into(), "3".into());
expected.insert(
    "player-upgrades".into(),
    "super-jump climbing lava-suit bombs".into(),
);

let result = file_to_key_value_map(Path::new("savedata.sav"))?;
assert_eq!(expected, result);
```

## Performance

- Uses `Box<str>` instead of `String` for reduced memory overhead
- Early termination on duplicate keys or I/O errors