yml_dict_li/
lib.rs

1#![feature(let_chains)]
2
3use std::{
4  fs::File,
5  io::{BufRead, BufReader},
6  path::Path,
7};
8
9pub fn set(
10  path: impl AsRef<Path>,
11  key: impl AsRef<str>,
12  value: impl AsRef<str>,
13) -> std::io::Result<Vec<(String, String)>> {
14  let path = path.as_ref();
15  let value = value.as_ref();
16  let key = key.as_ref();
17  let mut result = vec![];
18  let mut readed = vec![];
19  let kv = (key.to_owned(), value.to_owned());
20  if path.exists() {
21    let mut changed = false;
22    let mut has_key = false;
23    let file = File::open(path)?;
24    let reader = BufReader::new(file);
25    for line in reader.lines().map_while(Result::ok) {
26      let line = line.trim();
27      readed.push(line.to_owned());
28      if line.starts_with("#") {
29        continue;
30      }
31      if let Some(p) = line.find(":")
32        && (p + 1) < line.len()
33      {
34        let k = line[0..p].trim();
35        let v = line[p + 1..].trim();
36        if k == key {
37          has_key = true;
38          result.push(kv.clone());
39          if value != v {
40            changed = true;
41            readed.pop();
42            readed.push(format!("{key}: {value}"));
43          }
44        } else {
45          result.push((k.to_owned(), v.to_owned()));
46        }
47      }
48    }
49    if !has_key {
50      result.insert(0, kv);
51      changed = true;
52    }
53    if changed {
54      ifs::wstr(path, readed.join("\n"))?;
55    }
56  } else {
57    result.push(kv);
58    ifs::wstr(path, format!("{key}: {value}"))?;
59  }
60  Ok(result)
61}