//! Support module for writing `key=value` stores. //! //! These files are used by minetest mods (`mod.conf`), games (`game.conf`) and worlds //! (`world.mt`). //! //! Key-Value-Stores (KVStores) are represented by a [`std::collections::HashMap`] on the Rust //! side. use std::{collections::HashMap, fs, io::Write, path::Path}; use super::error::Result; /// Read the given file as a KVStore. pub fn read>(path: P) -> Result> { read_inner(path.as_ref()) } fn read_inner(path: &Path) -> Result> { let content = fs::read_to_string(path)?; Ok(content .lines() .map(|line| line.splitn(2, '=').map(str::trim).collect::>()) .map(|v| (v[0].into(), v[1].into())) .collect()) } /// Write the given KVStore back to the file. /// /// The order of the keys is guaranteed to be the following: /// /// 1. All options that *don't* start with `"load_mod_"` are saved in alphabetical order. /// 2. All remaining options are saved in alphabetical order. /// /// Note that this function will **override** existing files! pub fn write>(data: &HashMap, path: P) -> Result<()> { write_inner(data, path.as_ref()) } fn write_inner(data: &HashMap, path: &Path) -> Result<()> { let mut items = data.iter().collect::>(); items.sort_by_key(|i| (if i.0.starts_with("load_mod_") { 1 } else { 0 }, i.0)); let mut output = fs::File::create(path)?; for (key, value) in items { writeln!(output, "{} = {}", key, value)?; } Ok(()) }