houseflow_db/memory/
mod.rs

1use crate::{DatabaseInternalError, Error};
2use async_trait::async_trait;
3use houseflow_types::{Device, DeviceID, Room, Structure, User, UserID, UserStructure};
4use std::sync::Arc;
5use tokio::sync::Mutex;
6
7#[derive(Debug, thiserror::Error)]
8pub enum InternalError {}
9
10struct Admin {
11    user_id: UserID,
12}
13
14impl DatabaseInternalError for InternalError {}
15
16type ThreadVec<T> = Arc<Mutex<Vec<T>>>;
17
18#[derive(Clone, Default)]
19pub struct Database {
20    users: ThreadVec<User>,
21    admins: ThreadVec<Admin>,
22    structures: ThreadVec<Structure>,
23    rooms: ThreadVec<Room>,
24    user_structures: ThreadVec<UserStructure>,
25    devices: ThreadVec<Device>,
26}
27
28impl Database {
29    pub fn new() -> Self {
30        Default::default()
31    }
32}
33
34#[async_trait]
35impl crate::Database for Database {
36    async fn add_structure(&self, structure: &Structure) -> Result<(), Error> {
37        let mut structures = self.structures.lock().await;
38        structures.push(structure.clone());
39
40        Ok(())
41    }
42
43    async fn add_room(&self, room: &Room) -> Result<(), Error> {
44        let mut rooms = self.rooms.lock().await;
45        rooms.push(room.clone());
46
47        Ok(())
48    }
49
50    async fn add_device(&self, device: &Device) -> Result<(), Error> {
51        let mut devices = self.devices.lock().await;
52        devices.push(device.clone());
53        Ok(())
54    }
55
56    async fn add_user_structure(&self, user_structure: &UserStructure) -> Result<(), Error> {
57        let mut user_structures = self.user_structures.lock().await;
58        user_structures.push(user_structure.clone());
59        Ok(())
60    }
61
62    async fn add_user(&self, user: &User) -> Result<(), Error> {
63        let mut users = self.users.lock().await;
64        users.push(user.clone());
65        Ok(())
66    }
67
68    async fn get_device(&self, device_id: &DeviceID) -> Result<Option<Device>, Error> {
69        Ok(self
70            .devices
71            .lock()
72            .await
73            .iter()
74            .find(|device| device.id == *device_id)
75            .cloned())
76    }
77
78    async fn get_user_devices(&self, user_id: &UserID) -> Result<Vec<Device>, Error> {
79        let user_structures = self.user_structures.lock().await;
80        let rooms = self.rooms.lock().await;
81        let devices = self.devices.lock().await;
82        let user_devices = user_structures
83            .iter()
84            .filter(|user_structure| user_structure.user_id == *user_id)
85            .filter_map(|user_structure| {
86                rooms
87                    .iter()
88                    .find(|room| room.structure_id == user_structure.structure_id)
89            })
90            .filter_map(|room| devices.iter().find(|device| device.room_id == room.id))
91            .cloned()
92            .collect::<Vec<_>>();
93
94        Ok(user_devices)
95    }
96
97    async fn get_user(&self, user_id: &UserID) -> Result<Option<User>, Error> {
98        let user = self
99            .users
100            .lock()
101            .await
102            .iter()
103            .find(|user| user.id == *user_id)
104            .cloned();
105        Ok(user)
106    }
107
108    async fn get_user_by_email(&self, email: &str) -> Result<Option<User>, Error> {
109        let users = self.users.lock().await;
110        let user = users.iter().find(|user| user.email == *email).cloned();
111        Ok(user)
112    }
113
114    async fn check_user_device_access(
115        &self,
116        user_id: &UserID,
117        device_id: &DeviceID,
118    ) -> Result<bool, Error> {
119        let user_structures = self.user_structures.lock().await;
120        let rooms = self.rooms.lock().await;
121        let devices = self.devices.lock().await;
122        let have_access = user_structures
123            .iter()
124            .filter(|user_structure| user_structure.user_id == *user_id)
125            .filter_map(|user_structure| {
126                rooms
127                    .iter()
128                    .find(|room| room.structure_id == user_structure.structure_id)
129            })
130            .any(|room| {
131                devices
132                    .iter()
133                    .filter(|device| device.room_id == room.id)
134                    .any(|device| device.id == *device_id)
135            });
136
137        Ok(have_access)
138    }
139
140    async fn check_user_device_manager_access(
141        &self,
142        user_id: &UserID,
143        device_id: &DeviceID,
144    ) -> Result<bool, Error> {
145        let user_structures = self.user_structures.lock().await;
146        let rooms = self.rooms.lock().await;
147        let devices = self.devices.lock().await;
148        let have_access = user_structures
149            .iter()
150            .filter(|user_structure| {
151                user_structure.is_manager && user_structure.user_id == *user_id
152            })
153            .filter_map(|user_structure| {
154                rooms
155                    .iter()
156                    .find(|room| room.structure_id == user_structure.structure_id)
157            })
158            .any(|room| {
159                devices
160                    .iter()
161                    .filter(|device| device.room_id == room.id)
162                    .any(|device| device.id == *device_id)
163            });
164
165        Ok(have_access)
166    }
167
168    async fn check_user_admin(&self, user_id: &UserID) -> Result<bool, Error> {
169        let admins = self.admins.lock().await;
170        let is_admin = admins.iter().any(|admin| admin.user_id == *user_id);
171
172        Ok(is_admin)
173    }
174
175    async fn delete_user(&self, user_id: &UserID) -> Result<(), Error> {
176        let mut users = self.users.lock().await;
177        let pos = users
178            .iter()
179            .position(|user| user.id == *user_id)
180            .ok_or(Error::NotModified)?;
181        users.remove(pos);
182        Ok(())
183    }
184}