1use base64::DecodeError;
2use serde::{Deserialize, Serialize};
3use std::future::Future;
4use std::pin::Pin;
5use std::sync::Arc;
6use thiserror::Error;
7use uuid::Uuid;
8
9pub fn add(left: u64, right: u64) -> u64 {
10    left + right
11}
12
13#[cfg(test)]
14mod tests {
15    use super::*;
16
17    #[test]
18    fn it_works() {
19        let result = add(2, 2);
20        assert_eq!(result, 4);
21    }
22}
23
24pub type GetCallback = Arc<
33    dyn Fn(
34            GetEvent,
35        ) -> Pin<
36            Box<
37                dyn Future<Output = Result<bool, Box<dyn std::error::Error + Send + Sync>>>
38                    + Send
39                    + Sync,
40            >,
41        > + Send
42        + Sync,
43>;
44
45pub type InitCallback = Box<
54    dyn Fn(
55            InitProgressEvent,
56        ) -> Pin<
57            Box<
58                dyn Future<Output = Result<Option<bool>, Box<dyn std::error::Error + Send + Sync>>>
59                    + Send
60                    + Sync,
61            >,
62        > + Send
63        + Sync,
64>;
65
66pub type PurgeCallback = Arc<
73    dyn Fn(
74            PurgeEvent,
75        ) -> Pin<
76            Box<
77                dyn Future<Output = Result<bool, Box<dyn std::error::Error + Send + Sync>>>
78                    + Send
79                    + Sync,
80            >,
81        > + Send
82        + Sync,
83>;
84
85pub type SyncCallback = Arc<
92    dyn Fn(
93            SyncEvent,
94        ) -> Pin<
95            Box<
96                dyn Future<Output = Result<bool, Box<dyn std::error::Error + Send + Sync>>>
97                    + Send
98                    + Sync,
99            >,
100        > + Send
101        + Sync,
102>;
103
104pub type HealthCheckCallback = Arc<
111    dyn Fn(
112            HealthCheckEvent,
113        ) -> Pin<
114            Box<
115                dyn Future<Output = Result<bool, Box<dyn std::error::Error + Send + Sync>>>
116                    + Send
117                    + Sync,
118            >,
119        > + Send
120        + Sync,
121>;
122
123#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
125pub enum GetEvent {
126    Starting {
128        total_chunks: usize,
130    },
131    PadFetched,
133    Complete,
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
139pub enum InitProgressEvent {
140    Starting {
142        total_steps: u64,
144    },
145
146    Step {
148        step: u64,
150        message: String,
152    },
153
154    PromptCreateRemoteIndex,
157
158    Failed {
160        error_msg: String,
162    },
163
164    Complete {
166        message: String,
168    },
169}
170
171#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
173pub enum PurgeEvent {
174    Starting {
176        total_count: usize,
178    },
179
180    PadProcessed,
182
183    Complete {
185        verified_count: usize,
187        failed_count: usize,
189    },
190}
191
192#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
194pub enum SyncEvent {
195    FetchingRemoteIndex,
197
198    Merging,
200
201    PushingRemoteIndex,
203
204    VerifyingRemoteIndex,
206
207    Complete,
209}
210
211#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
213pub enum HealthCheckEvent {
214    Starting {
216        total_keys: usize,
218    },
219
220    KeyProcessed,
222
223    Complete {
225        nb_keys_updated: usize,
227    },
228}
229
230pub type TaskId = Uuid;
233
234#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
235pub enum TaskType {
236    Put,
237    Get,
238    Sync,
239    Purge,
240    HealthCheck,
241    Rm,
242}
243
244#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
245pub enum TaskStatus {
246    Stopped,
247    Pending,
248    InProgress,
249    Completed,
250    Failed,
251}
252
253#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
254pub enum PutEvent {
255    Starting {
256        total_chunks: usize,
257        initial_written_count: usize,
258        initial_confirmed_count: usize,
259        chunks_to_reserve: usize,
260    },
261    PadReserved,
262    PadsWritten,
263    PadsConfirmed,
264    Complete,
265}
266
267pub type PutCallback = Arc<
268    dyn Fn(
269            PutEvent,
270        ) -> Pin<
271            Box<
272                dyn Future<Output = Result<bool, Box<dyn std::error::Error + Send + Sync>>>
273                    + Send
274                    + Sync,
275            >,
276        > + Send
277        + Sync,
278>;
279
280#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
281pub enum TaskProgress {
282    Put(PutEvent),
283    Get(GetEvent),
284    Sync(SyncEvent),
285    Purge(PurgeEvent),
286    HealthCheck(HealthCheckEvent),
287}
288
289#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
290pub enum TaskResult {
291    Pending,
292    Error(String),
293    Result(TaskResultType),
294}
295
296#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
297pub enum TaskResultType {
298    Put(PutResult),
299    Get(GetResult),
300    Sync(SyncResult),
301    Purge(PurgeResult),
302    HealthCheck(HealthCheckResult),
303}
304
305#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
307pub struct PutResult {
308    pub public_address: Option<String>,
310}
311
312#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
313pub struct Task {
314    pub id: TaskId,
315    pub task_type: TaskType,
316    pub status: TaskStatus,
317    pub progress: Option<TaskProgress>,
318    pub result: TaskResult,
319    pub key: Option<String>, }
321
322#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
327pub struct PutRequest {
328    pub user_key: String,
329    pub source_path: String, pub mode: StorageMode,
331    pub public: bool,
332    pub no_verify: bool,
333}
334
335#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
336pub struct GetRequest {
337    pub user_key: String,
338    pub destination_path: String, pub public: bool,
340}
341
342#[derive(Deserialize, Debug, PartialEq, Eq, Serialize, Clone)]
343pub struct QueryTaskRequest {
344    pub task_id: Uuid,
345}
346
347#[derive(Deserialize, Debug, PartialEq, Eq, Serialize, Clone)]
348pub struct ListTasksRequest;
349
350#[derive(Deserialize, Debug, PartialEq, Eq, Serialize, Clone)]
351pub struct StopTaskRequest {
352    pub task_id: Uuid,
353}
354
355#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
356pub struct RmRequest {
357    pub user_key: String,
358}
359
360#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
361pub struct ListKeysRequest;
362
363#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
364pub struct PurgeRequest {
365    pub aggressive: bool,
366}
367
368#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
370#[serde(tag = "type")]
371pub enum Request {
372    Put(PutRequest),
373    Get(GetRequest),
374    QueryTask(QueryTaskRequest),
375    ListTasks(ListTasksRequest),
376    StopTask(StopTaskRequest),
377    Rm(RmRequest),
378    ListKeys(ListKeysRequest),
379    Stats(StatsRequest),
380    Sync(SyncRequest),
381    Purge(PurgeRequest),
382    Import(ImportRequest),
383    Export(ExportRequest),
384    HealthCheck(HealthCheckRequest),
385}
386
387#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
390pub struct TaskCreatedResponse {
391    pub task_id: Uuid,
392}
393
394#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
395pub struct TaskUpdateResponse {
396    pub task_id: TaskId,
397    pub status: TaskStatus,
398    pub progress: Option<TaskProgress>,
399}
400
401#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
402pub struct TaskResultResponse {
403    pub task_id: Uuid,
404    pub status: TaskStatus,
405    pub result: TaskResult,
406}
407
408#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
409pub struct TaskStoppedResponse {
410    pub task_id: Uuid,
411}
412
413#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
414pub struct TaskListEntry {
415    pub task_id: Uuid,
416    pub task_type: TaskType,
417    pub status: TaskStatus,
418}
419
420#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
421pub struct TaskListResponse {
422    pub tasks: Vec<TaskListEntry>,
423}
424
425#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
426pub struct ErrorResponse {
427    pub error: String,
428    pub original_request: Option<String>, }
430
431#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
432pub struct RmSuccessResponse {
433    pub user_key: String,
434}
435
436#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
438pub struct KeyDetails {
439    pub key: String,
440    pub total_size: usize,
441    pub pad_count: usize,
442    pub confirmed_pads: usize,
443    pub is_public: bool,
444    pub public_address: Option<String>, }
446
447#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
448pub struct ListKeysResponse {
449    pub keys: Vec<KeyDetails>,
450}
451
452#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
454pub struct StatsRequest {}
455
456#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
457pub struct StatsResponse {
458    pub total_keys: u64,
459    pub total_pads: u64,
460    pub occupied_pads: u64,
461    pub free_pads: u64,
462    pub pending_verify_pads: u64,
463}
464#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
467pub struct SyncRequest {
468    pub push_force: bool,
469}
470
471#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
472pub struct SyncResponse {
473    pub result: SyncResult,
474}
475
476#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
477pub struct SyncResult {
478    pub nb_keys_added: usize,
479    pub nb_keys_updated: usize,
480    pub nb_free_pads_added: usize,
481    pub nb_pending_pads_added: usize,
482}
483
484#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
486pub struct GetResult {
487    pub size: usize,
489}
490
491#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
492pub struct PurgeResponse {
493    pub result: PurgeResult,
494}
495
496#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
497pub struct PurgeResult {
498    pub nb_pads_purged: usize,
499}
500
501#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
502pub struct ImportRequest {
503    pub file_path: String,
504}
505
506#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
507pub struct ImportResponse {
508    pub result: ImportResult,
509}
510
511#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
512pub struct ImportResult {
513    pub nb_keys_imported: usize,
514}
515
516#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
517pub struct ExportRequest {
518    pub destination_path: String,
519}
520
521#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
522pub struct ExportResponse {
523    pub result: ExportResult,
524}
525
526#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
527pub struct ExportResult {
528    pub nb_keys_exported: usize,
529}
530
531#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
532pub struct HealthCheckRequest {
533    pub key_name: String,
534    pub recycle: bool,
535}
536
537#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
538pub struct HealthCheckResponse {
539    pub result: HealthCheckResult,
540}
541
542#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
543pub struct HealthCheckResult {
544    pub nb_keys_reset: usize,
545    pub nb_keys_recycled: usize,
546}
547
548#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
550#[serde(tag = "type")]
551pub enum Response {
552    Error(ErrorResponse),
553    TaskCreated(TaskCreatedResponse),
554    TaskUpdate(TaskUpdateResponse),
555    TaskResult(TaskResultResponse),
556    TaskStopped(TaskStoppedResponse),
557    TaskList(TaskListResponse),
558    RmSuccess(RmSuccessResponse),
559    ListKeys(ListKeysResponse),
560    Stats(StatsResponse),
561    Import(ImportResponse),
562    Export(ExportResponse),
563}
564
565#[derive(Error, Debug)]
579pub enum ProtocolError {
580    #[error("JSON serialization error: {0}")]
581    Serialization(#[from] serde_json::Error),
582
583    #[error("JSON deserialization error: {0}")]
585    Deserialization(serde_json::Error),
586
587    #[error("Base64 decoding error: {0}")]
588    Base64Decode(#[from] DecodeError),
589
590    #[error("Task not found: {0}")]
591    TaskNotFound(Uuid),
592
593    #[error("Invalid request format: {0}")]
594    InvalidRequest(String),
595
596    #[error("Internal server error: {0}")] InternalError(String),
598
599    #[error("WebSocket error: {0}")] WebSocket(String),
601}
602
603pub const LIGHTEST_SCRATCHPAD_SIZE: usize = 512 * 1024;
604pub const LIGHT_SCRATCHPAD_SIZE: usize = 1 * 1024 * 1024;
605pub const MEDIUM_SCRATCHPAD_SIZE: usize = 2 * 1024 * 1024;
606pub const HEAVY_SCRATCHPAD_SIZE: usize = 3 * 1024 * 1024;
607pub const HEAVIEST_SCRATCHPAD_SIZE: usize = (4 * 1024 * 1024) - 4096;
608
609#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
610pub enum StorageMode {
611    Lightest,
613    Light,
615    Medium,
617    Heavy,
619    Heaviest,
621}
622
623impl StorageMode {
624    pub fn scratchpad_size(&self) -> usize {
625        match self {
626            StorageMode::Lightest => LIGHTEST_SCRATCHPAD_SIZE,
627            StorageMode::Light => LIGHT_SCRATCHPAD_SIZE,
628            StorageMode::Medium => MEDIUM_SCRATCHPAD_SIZE,
629            StorageMode::Heavy => HEAVY_SCRATCHPAD_SIZE,
630            StorageMode::Heaviest => HEAVIEST_SCRATCHPAD_SIZE,
631        }
632    }
633}