1use crate::schema::file_records;
2use diesel::prelude::*;
3use serde::{Deserialize, Serialize};
4use time::OffsetDateTime;
5
6use diesel::{AsExpression, FromSqlRow};
7
8use diesel::sql_types::Integer;
9
10#[repr(i32)]
11#[derive(Debug, Clone, Copy, AsExpression, FromSqlRow, PartialEq, Deserialize, Serialize)]
12#[diesel(sql_type = Integer)]
13pub enum FileFormat {
14 Binary = 1,
15 Text = 2,
16}
17
18#[derive(Debug)]
19pub enum IndexerUpdateEvent {
20 Updated,
21}
22
23#[derive(Queryable, Selectable, Identifiable, Debug, Clone)]
24#[diesel(table_name = file_records)]
25#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
26pub struct FileRecord {
27 pub id: i32,
28 pub jid: Option<i32>,
29 pub deleted: bool,
30 pub path: String,
31 pub size: i64,
32 pub modified_at: OffsetDateTime,
33 pub namespace_id: i32,
34}
35
36#[derive(Insertable, Debug, Clone)]
37#[diesel(table_name = file_records)]
38#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
39pub struct CreateForm {
40 pub jid: Option<i32>,
41 pub path: String,
42 pub deleted: bool,
43 pub size: i64,
44 pub modified_at: OffsetDateTime,
45 pub namespace_id: i32,
46}
47
48#[derive(Insertable, Debug, Clone)]
49#[diesel(table_name = file_records)]
50#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
51pub struct DeleteForm {
52 pub path: String,
53 pub jid: Option<i32>,
54 pub size: i64,
55 pub modified_at: OffsetDateTime,
56 pub deleted: bool,
57 pub namespace_id: i32,
58}
59
60#[derive(AsChangeset, Debug, Clone)]
61#[diesel(table_name = file_records)]
62#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
63pub struct FileRecordUpdateForm {
64 pub size: i64,
65 pub modified_at: OffsetDateTime,
66}
67
68#[derive(AsChangeset, Debug, Clone)]
69#[diesel(table_name = file_records)]
70#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
71pub struct FileRecordNonDeletedFilterForm {
72 pub deleted: bool,
73}
74
75#[derive(AsChangeset, Debug, Clone)]
76#[diesel(table_name = file_records)]
77#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
78pub struct FileRecordDeleteForm {
79 pub id: i32,
80 pub deleted: bool,
81 pub namespace_id: i32,
82}
83
84impl PartialEq<CreateForm> for FileRecord {
85 fn eq(&self, other: &CreateForm) -> bool {
86 self.path == other.path && self.size == other.size && self.modified_at == other.modified_at
87 }
88}
89
90#[derive(Debug, Clone, uniffi::Enum)]
92pub enum SyncStatus {
93 Idle,
95 Syncing,
97 Indexing,
99 Downloading,
101 Uploading,
103 Error { message: String },
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110 use time::OffsetDateTime;
111
112 #[test]
113 fn test_file_format_values() {
114 assert_eq!(FileFormat::Binary as i32, 1);
115 assert_eq!(FileFormat::Text as i32, 2);
116 }
117
118 #[test]
119 fn test_file_format_equality() {
120 assert_eq!(FileFormat::Binary, FileFormat::Binary);
121 assert_eq!(FileFormat::Text, FileFormat::Text);
122 assert_ne!(FileFormat::Binary, FileFormat::Text);
123 }
124
125 #[test]
126 fn test_file_record_create_form_equality() {
127 let now = OffsetDateTime::now_utc();
128
129 let record = FileRecord {
130 id: 1,
131 jid: Some(100),
132 deleted: false,
133 path: "test/path.txt".to_string(),
134 size: 1024,
135 modified_at: now,
136 namespace_id: 1,
137 };
138
139 let form = CreateForm {
140 jid: Some(100),
141 path: "test/path.txt".to_string(),
142 deleted: false,
143 size: 1024,
144 modified_at: now,
145 namespace_id: 1,
146 };
147
148 assert_eq!(record, form);
150 }
151
152 #[test]
153 fn test_file_record_create_form_inequality_different_path() {
154 let now = OffsetDateTime::now_utc();
155
156 let record = FileRecord {
157 id: 1,
158 jid: Some(100),
159 deleted: false,
160 path: "test/path1.txt".to_string(),
161 size: 1024,
162 modified_at: now,
163 namespace_id: 1,
164 };
165
166 let form = CreateForm {
167 jid: Some(100),
168 path: "test/path2.txt".to_string(),
169 deleted: false,
170 size: 1024,
171 modified_at: now,
172 namespace_id: 1,
173 };
174
175 assert_ne!(record, form);
177 }
178
179 #[test]
180 fn test_file_record_create_form_inequality_different_size() {
181 let now = OffsetDateTime::now_utc();
182
183 let record = FileRecord {
184 id: 1,
185 jid: Some(100),
186 deleted: false,
187 path: "test/path.txt".to_string(),
188 size: 1024,
189 modified_at: now,
190 namespace_id: 1,
191 };
192
193 let form = CreateForm {
194 jid: Some(100),
195 path: "test/path.txt".to_string(),
196 deleted: false,
197 size: 2048,
198 modified_at: now,
199 namespace_id: 1,
200 };
201
202 assert_ne!(record, form);
204 }
205
206 #[test]
207 fn test_create_form_construction() {
208 let now = OffsetDateTime::now_utc();
209
210 let form = CreateForm {
211 jid: Some(42),
212 path: "recipes/test.cook".to_string(),
213 deleted: false,
214 size: 512,
215 modified_at: now,
216 namespace_id: 5,
217 };
218
219 assert_eq!(form.jid, Some(42));
220 assert_eq!(form.path, "recipes/test.cook");
221 assert_eq!(form.deleted, false);
222 assert_eq!(form.size, 512);
223 assert_eq!(form.namespace_id, 5);
224 }
225
226 #[test]
227 fn test_delete_form_construction() {
228 let now = OffsetDateTime::now_utc();
229
230 let form = DeleteForm {
231 path: "recipes/deleted.cook".to_string(),
232 jid: Some(99),
233 size: 0,
234 modified_at: now,
235 deleted: true,
236 namespace_id: 1,
237 };
238
239 assert_eq!(form.path, "recipes/deleted.cook");
240 assert_eq!(form.deleted, true);
241 assert_eq!(form.size, 0);
242 }
243
244 #[test]
245 fn test_file_record_update_form() {
246 let now = OffsetDateTime::now_utc();
247
248 let update_form = FileRecordUpdateForm {
249 size: 2048,
250 modified_at: now,
251 };
252
253 assert_eq!(update_form.size, 2048);
254 assert_eq!(update_form.modified_at, now);
255 }
256
257 #[test]
258 fn test_sync_status_variants() {
259 let idle = SyncStatus::Idle;
260 let syncing = SyncStatus::Syncing;
261 let indexing = SyncStatus::Indexing;
262 let downloading = SyncStatus::Downloading;
263 let uploading = SyncStatus::Uploading;
264 let error = SyncStatus::Error {
265 message: "Test error".to_string(),
266 };
267
268 assert!(matches!(idle, SyncStatus::Idle));
270 assert!(matches!(syncing, SyncStatus::Syncing));
271 assert!(matches!(indexing, SyncStatus::Indexing));
272 assert!(matches!(downloading, SyncStatus::Downloading));
273 assert!(matches!(uploading, SyncStatus::Uploading));
274 assert!(matches!(error, SyncStatus::Error { .. }));
275 }
276}