1#[derive(Default, Debug, Clone, Hash, Eq, PartialEq)]
5pub enum CancelReason {
6 #[default]
8 Unknown,
9 Shutdown,
11 Closed,
13 UserCanceled,
15 Aborted,
20}
21
22#[cfg(feature = "files")]
23mod files {
24 use sos_core::events::FileEvent;
26
27 use sos_core::ExternalFile;
28 use sos_external_files::FileMutationEvent;
29
30 use crate::transfer::CancelReason;
31 use async_trait::async_trait;
32 use http::StatusCode;
33 use indexmap::IndexSet;
34 use std::path::Path;
35 use tokio::sync::watch;
36
37 pub type ProgressChannel = tokio::sync::mpsc::Sender<(u64, Option<u64>)>;
39
40 pub type FileTransferQueueRequest = Vec<FileOperation>;
42
43 pub type FileTransferQueueSender =
45 tokio::sync::broadcast::Sender<FileTransferQueueRequest>;
46
47 #[derive(Debug, Default, Clone, PartialEq, Eq)]
49 pub struct FileSet(pub IndexSet<ExternalFile>);
50
51 #[derive(Debug, Default, Clone, PartialEq, Eq)]
54 pub struct FileTransfersSet {
55 pub uploads: FileSet,
57 pub downloads: FileSet,
59 }
60
61 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
63 pub enum TransferOperation {
64 Upload,
66 Download,
68 Delete,
70 Move(ExternalFile),
72 }
73
74 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
76 pub struct FileOperation(pub ExternalFile, pub TransferOperation);
77
78 impl From<&FileMutationEvent> for FileOperation {
79 fn from(value: &FileMutationEvent) -> Self {
80 match value {
81 FileMutationEvent::Create { event, .. } => event.into(),
82 FileMutationEvent::Move(event) => event.into(),
83 FileMutationEvent::Delete(event) => event.into(),
84 }
85 }
86 }
87
88 impl From<&FileEvent> for FileOperation {
89 fn from(value: &FileEvent) -> Self {
90 match value {
91 FileEvent::CreateFile(owner, file_name) => FileOperation(
92 ExternalFile::new(*owner, *file_name),
93 TransferOperation::Upload,
94 ),
95 FileEvent::DeleteFile(owner, file_name) => FileOperation(
96 ExternalFile::new(*owner, *file_name),
97 TransferOperation::Delete,
98 ),
99 FileEvent::MoveFile { name, from, dest } => FileOperation(
100 ExternalFile::new(*from, *name),
101 TransferOperation::Move(ExternalFile::new(*dest, *name)),
102 ),
103 _ => panic!("attempt to convert noop file event"),
104 }
105 }
106 }
107
108 #[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
110 #[cfg_attr(not(target_arch = "wasm32"), async_trait)]
111 pub trait FileSyncClient {
112 type Error: std::error::Error + std::fmt::Debug;
114
115 async fn upload_file(
117 &self,
118 file_info: &ExternalFile,
119 path: &Path,
120 progress: ProgressChannel,
121 cancel: watch::Receiver<CancelReason>,
122 ) -> Result<StatusCode, Self::Error>;
123
124 async fn download_file(
126 &self,
127 file_info: &ExternalFile,
128 path: &Path,
129 progress: ProgressChannel,
130 cancel: watch::Receiver<CancelReason>,
131 ) -> Result<StatusCode, Self::Error>;
132
133 async fn delete_file(
135 &self,
136 file_info: &ExternalFile,
137 ) -> Result<StatusCode, Self::Error>;
138
139 async fn move_file(
141 &self,
142 from: &ExternalFile,
143 to: &ExternalFile,
144 ) -> Result<StatusCode, Self::Error>;
145
146 async fn compare_files(
155 &self,
156 local_files: FileSet,
157 ) -> Result<FileTransfersSet, Self::Error>;
158 }
159}
160
161#[cfg(feature = "files")]
162pub use files::*;