INI
INI files read and written, sections and keys: php.ini, setup.cfg, .gitconfig and the settings of older software.
Version 1.0.0 · 3 functions · 1 crate
Functions
What use ini.qwer gives a program, with the types Quillo sees. To take only some, or under other names: use ini_parse, ini_read_file from ini (Quillo 0.6).
ini_parse(text: str) → anyor an errorINI text as a map: each [section] a map of its keys, keys before the first section at the top. Values are text, with quotes around them taken off (name = "Ada"); ; and # start comments; a key given twice keeps the last. Sections named a.b stay one key, "a.b".
ini_read_file(path: str) → anyor an errorAn INI file read as ini_parse reads text.
ini_write(value: any) → stror an errorA map as INI text: values that are maps become [sections] (in the map's order of keys, sorted), the others keys at the top. Numbers and booleans are written as text, null as nothing; a line break in a value is an error, since INI has none.
Get it
$ quillo install ini # ini.qwer into this folder$ quillo install ini --example # and its example, ini.qweOr with curl:
$ curl -O https://quillolang.org/plugins/files/ini.qwer$ curl -O https://quillolang.org/plugins/files/ini.qwe$ curl -O https://quillolang.org/plugins/files/ini_sample.iniThen, in your program, all of it or only what you call:
use ini.qweruse ini_parse, ini_read_file from ini // Quillo 0.6: only theseIt uses this crate, which cargo fetches the first time the plugin is built:
rust-ini = "0.21"Example
// Settings imported from an old app's .ini file, and written back with a change.//// quillo run ini.qwe then open http://localhost:8080/settingsuse "ini.qwer"route GET /settings { let s = ini_read_file("ini_sample.ini")? { app: s.app_name, debug: s.debug == "true", db: `postgres://${s.database.host}:${int(s.database.port)?}/${s.database.name}`, from: s.mail.from, uploads: s.paths.uploads }}route GET /updated.ini { let s = ini_read_file("ini_sample.ini")? respond(200, ini_write({ ...s, debug: true, database: { ...s.database, host: "db2.internal" } })?, { "content-type": "text/plain; charset=utf-8" })}$ quillo run ini.qwe$ curl 'localhost:8080/settings'$ curl 'localhost:8080/updated.ini'Source
//! INI files read and written (`[section]` and `key = value`): php.ini, setup.cfg, .gitconfig, desktop files and the settings of older Windows software.//! version: 1.0.0//!//! [dependencies]//! rust-ini = "0.21"use ini::{EscapePolicy, Ini, ParseOption, WriteOption};use serde_json::{Map, Value};/// Files up to 10 MB are read.const MAX: usize = 10 * 1024 * 1024;fn to_map(ini: &Ini) -> Value { let mut out = Map::new(); for (sec, props) in ini.iter() { match sec { None => { for (k, v) in props.iter() { out.insert(k.to_string(), Value::String(v.to_string())); } } Some(name) => { let entry = out.entry(name.to_string()).or_insert_with(|| Value::Object(Map::new())); if !entry.is_object() { *entry = Value::Object(Map::new()); } if let Value::Object(m) = entry { for (k, v) in props.iter() { m.insert(k.to_string(), Value::String(v.to_string())); } } } } } Value::Object(out)}/// INI text as a map: each `[section]` a map of its keys, keys before the first section at the top. Values are text, with/// quotes around them taken off (`name = "Ada"`); `;` and `#` start comments; a key given twice keeps the last. Sections named/// `a.b` stay one key, `"a.b"`.pub fn ini_parse(text: &str) -> Result<Value, String> { if text.len() > MAX { return Err("INI files up to 10 MB".into()); } let ini = Ini::load_from_str_opt(text, ParseOption { enabled_quote: true, enabled_escape: false, ..ParseOption::default() }).map_err(|e| format!("not INI: {}", e))?; Ok(to_map(&ini))}/// An INI file read as ini_parse reads text.pub fn ini_read_file(path: &str) -> Result<Value, String> { let size = std::fs::metadata(path).map_err(|e| format!("{}: {}", path, e))?.len(); if size as usize > MAX { return Err(format!("{}: INI files up to 10 MB", path)); } ini_parse(&std::fs::read_to_string(path).map_err(|e| format!("{}: {}", path, e))?)}fn text(v: &Value) -> String { match v { Value::String(s) => s.clone(), Value::Null => String::new(), other => other.to_string(), }}/// A map as INI text: values that are maps become `[sections]` (in the map's order of keys, sorted), the others keys at the top./// Numbers and booleans are written as text, null as nothing; a line break in a value is an error, since INI has none.pub fn ini_write(value: serde_json::Value) -> Result<String, String> { let Value::Object(m) = value else { return Err("INI is written from a map".into()) }; let mut ini = Ini::new(); let check = |k: &str, v: &str| if v.contains('\n') || k.contains('\n') || k.contains('=') { Err(format!("`{}`: INI keys and values are one line, without `=` in a key", k)) } else { Ok(()) }; for (k, v) in &m { if !v.is_object() { let t = text(v); check(k, &t)?; ini.with_general_section().set(k.as_str(), t); } } for (name, v) in &m { if let Value::Object(props) = v { for (k, x) in props { let t = text(x); check(k, &t)?; ini.with_section(Some(name.as_str())).set(k.as_str(), t); } if props.is_empty() { ini.with_section(Some(name.as_str())); } } } let mut out = Vec::new(); ini.write_to_opt(&mut out, WriteOption { escape_policy: EscapePolicy::Nothing, kv_separator: " = ", ..WriteOption::default() }).map_err(|e| e.to_string())?; String::from_utf8(out).map_err(|e| e.to_string())}Related
json5.qwer · 1.0.0JSON5 and JSON with comments read as values: tsconfig.json and editor settings, with comments, trailing commas and unquoted keys.7 views · 8 downloads.env files dotenv.qwer · 1.0.0.env files read with their quoting rules and ${VAR} expansion, linted and compared with .env.example, and written or changed one key at a time with comments kept.8 views · 9 downloadsAvro avro.qwer · 1.0.0Apache Avro data files: rows written with a schema, as Kafka, Hadoop and BigQuery use, and read back with the schema they carry.9 views · 6 downloadsBibTeX bibtex.qwer · 1.0.0BibTeX and BibLaTeX bibliographies read, with LaTeX accents and macros resolved; reference lists in APA or IEEE style, CSL-JSON for Zotero and pandoc, and entries written back.7 views · 6 downloadsCSV csv.qwer · 1.0.0CSV in and out: rows as maps keyed by the header, with quotes, commas and line breaks in cells handled.8 views · 8 downloadsFixed width fixed_width.qwer · 1.0.0Fixed-width records read and written from a column spec: bank payment files, payroll exports and mainframe formats.8 views · 8 downloadsThread 0 posts
On INI: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.