houseflow_db/memory/
mod.rs1use 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}