filedb_ng/
lib.rs

1//! # `filedb`
2//! A **library-only** database that uses files instead of single monolith `.db` file.
3//! It's very simple, since it only handles writing and reading to/from files and doesn't include encryption and CLI.
4//! > You have to do these things yourself, either through having the database on something like [VeraCrypt volume](https://veracrypt.org) or on another machine.
5//! Anyway, take a look around.
6use serde::{Deserialize, Serialize};
7use std::path::Path;
8/// Main struct that handles the database
9#[derive(Default, Serialize, Deserialize)]
10pub struct DB<Struct: Serialize> {
11    // row
12    db_row: String,
13    // location of the database
14    db_location: String,
15    table: String, // aka directory
16    // contents
17    contents: Option<Struct>,
18}
19impl<Struct: Serialize + Default + for<'de> serde::Deserialize<'de>>
20    DB<Struct>
21{
22    /// Initializes the database
23    pub fn new(location: String) -> Self {
24        if Path::new(&location).exists() == false {
25            std::fs::DirBuilder::new()
26                .recursive(true)
27                .create(&location)
28                .unwrap()
29        }
30        Self {
31            db_row: "".to_string(),
32            db_location: location,
33            table: "".to_string(),
34            contents: Default::default(),
35        }
36    }
37    /// Populates the database with content
38    pub fn populate(
39        &mut self,
40        table: String,
41        row: String,
42        contents: Option<Struct>,
43    ) {
44        let join = Path::new(&self.db_location).join(&table);
45        match join.exists() {
46            true => (),
47            false => {
48                std::fs::DirBuilder::new()
49                    .recursive(true)
50                    .create(&join)
51                    .unwrap()
52            }
53        };
54        self.table = table;
55        self.contents = contents;
56        self.db_row = row;
57        let toml = toml::to_string_pretty(&self.contents)
58            .unwrap_or("The databse doesn't exist yet".to_string());
59        std::fs::write(
60            Path::new(join.to_str().unwrap()).join(&self.db_row),
61            toml,
62        )
63        .unwrap()
64    }
65    /// Opens the database
66    pub fn open(self, table: String, row: String) -> Struct {
67        let path = Path::new(&self.db_location).join(table).join(row);
68        let f = std::fs::read_to_string(&path).unwrap();
69        toml::from_str::<Struct>(f.as_str()).unwrap()
70    }
71}
72#[cfg(test)]
73mod tests {
74    use super::*;
75    use serde::{Deserialize, Serialize};
76
77    #[derive(Serialize, Deserialize, Default)]
78    struct Data {
79        name: String,
80        surname: String,
81    }
82    #[test]
83    fn test_create_db() {
84        // Initialize the database
85        let mut db: DB<Data> = DB::new("database".to_string());
86        db.populate("id".to_string(), "personal".to_string(), None);
87        std::fs::remove_dir_all("database").unwrap()
88    }
89}