jsn_base/
lib.rs

1use serde::{Deserialize, Serialize};
2use std::marker::PhantomData;
3use std::fs;
4use std::io;
5
6#[allow(dead_code)]
7pub struct Connection {
8    uri: String,
9}
10
11impl Connection {
12    /// Create new connection
13    /// 
14    /// `uri` is a path of a folder, where data will be stored.
15    pub fn new(uri: &str) -> Result<Self, io::Error> {
16        let _ = fs::create_dir_all(&uri)?;
17
18        Ok(Self {
19            uri: uri.to_string(),
20        })
21    }
22}
23
24#[derive(Serialize, Deserialize, Debug)]
25pub struct Model<T> {
26    name: String,
27    data: Vec<T>,
28    ty: PhantomData<T>,
29    uri: String,
30}
31
32impl<T: Serialize + for<'a> Deserialize<'a>> Model<T> {
33    /// Create a new Modal instance.
34    ///
35    /// `name` is name of the modal.
36    /// `connection` connection reference.
37    pub fn new(name: &str, connection: &Connection) -> Self {
38        Self {
39            name: name.to_string(),
40            data: Vec::new(),
41            ty: PhantomData::<T>,
42            uri: connection.uri.to_string(),
43        }
44    }
45
46    fn get_path(&self) -> String {
47        format!("{}/{}.jsnbase", &self.uri, &self.name)
48    }
49
50    /// load
51    ///
52    /// load previous state of data.
53    pub fn load(&mut self) {
54        if let Ok(contents) = std::fs::read_to_string(&self.get_path()) {
55            if let Ok(prased_contents) = serde_json::from_str::<Model<T>>(&contents) {
56                self.data = prased_contents.data;
57            };
58
59            // TODO: handle Error
60        }
61    }
62
63    /// save
64    ///
65    /// save the current state of data.
66    pub fn save(&self) {
67        // TODO: handle error
68
69        let contents = serde_json::to_string(&self).unwrap();
70
71        let _ = std::fs::write(&self.get_path(), &contents);
72    }
73
74    /// create
75    ///
76    /// creates a new record
77    pub fn create(&mut self, payload: T) -> Option<&T> {
78        self.data.push(payload);
79
80        self.data.get(self.data.len() - 1)
81    }
82
83    /// creates
84    ///
85    /// create many new record.
86    pub fn creates(&mut self, payloads: Vec<T>) -> () {
87        payloads.into_iter().for_each(|item| {
88            self.create(item);
89        });
90    }
91
92    /// get
93    ///
94    /// get a single item.
95    pub fn get(&self, condition: impl Fn(&T) -> bool) -> Option<&T> {
96        self.data.iter().find(|item| condition(*item))
97    }
98
99    /// gets
100    ///
101    /// get many item.
102    pub fn gets(&self, condition: impl Fn(&T) -> bool) -> Vec<&T> {
103        self.data.iter().filter(|item| condition(*item)).collect()
104    }
105
106    /// remove
107    ///
108    /// remove a single item.
109    pub fn remove(&mut self, condition: impl Fn(&T) -> bool) -> Option<T> {
110        match self.data.iter().position(|item| condition(item)) {
111            Some(index) => Some(self.data.remove(index)),
112            _ => None,
113        }
114    }
115
116    /// removes
117    ///
118    /// remove many item.
119    pub fn removes(&mut self, condition: impl Fn(&T) -> bool) {
120        while let Some(_) = self.remove(&condition) {
121            //
122        }
123    }
124}