1use crate::db::DB;
10use std::collections::HashMap;
11use std::fs::File;
12use std::io::Write;
13use std::path::Path;
14use std::{fs, io};
15
16pub fn db(db: &DB, to: &Path) -> Result<(), io::Error> {
17 if to.is_dir() {
18 let parent = to.parent().expect("Cannot write to /");
19 rules_dir(db, to, &parent.join("compiled.rules"))
20 } else {
21 rules_file(db, to)
22 }
23}
24
25fn rules_dir(db: &DB, dir: &Path, compiled: &Path) -> Result<(), io::Error> {
26 let mut files = HashMap::<&str, Vec<String>>::new();
27 for (_, (k, v)) in db.iter() {
28 if !files.contains_key(k.as_str()) {
29 files.insert(k, vec![]);
30 }
31 files.get_mut(k.as_str()).unwrap().push(v.to_string());
32 }
33
34 for e in fs::read_dir(dir)? {
36 let f = e?.path();
37 if f.display().to_string().ends_with(".rules") {
38 fs::remove_file(f)?;
39 }
40 }
41
42 for (k, v) in files {
44 let mut rf = File::create(dir.join(k))?;
45 for l in v {
46 rf.write_all(format!("{}\n", l).as_bytes())?;
47 }
48 }
49
50 let mut rf = File::create(compiled)?;
53 for (_, (_, e)) in db.iter() {
54 rf.write_all(format!("{}\n", e).as_bytes())?;
55 }
56
57 Ok(())
58}
59
60fn rules_file(db: &DB, to: &Path) -> Result<(), io::Error> {
61 let mut rf = File::create(to)?;
62 for (_, (_, e)) in db.iter() {
63 rf.write_all(format!("{}\n", e).as_bytes())?;
64 }
65 Ok(())
66}