1use std::future::Future;
4
5use bytes::Bytes;
6use chrono::DateTime;
7use chrono::Utc;
8use serde::Deserialize;
9use serde::Serialize;
10use tokio_util::sync::CancellationToken;
11
12use crate::dynamic::BoxStream;
13use crate::error::ProviderError;
14use crate::shared::Headers;
15use crate::shared::MediaType;
16use crate::shared::ProviderId;
17use crate::shared::ProviderMetadata;
18use crate::shared::ProviderOptions;
19use crate::shared::ProviderReference;
20use crate::shared::Warning;
21
22pub trait Files: Send + Sync + 'static {
28 fn provider(&self) -> &ProviderId;
30
31 fn upload_file(
33 &self,
34 options: UploadFileOptions,
35 ) -> impl Future<Output = Result<UploadFileResult, ProviderError>> + Send;
36
37 fn supports_get_file_metadata(&self) -> bool {
39 false
40 }
41
42 fn get_file_metadata(
44 &self,
45 options: FileReferenceOptions,
46 ) -> impl Future<Output = Result<FileMetadataResult, ProviderError>> + Send {
47 let _ = options;
48 std::future::ready(Err(ProviderError::unsupported("get_file_metadata")))
49 }
50
51 fn supports_download_file(&self) -> bool {
53 false
54 }
55
56 fn download_file(
58 &self,
59 options: FileReferenceOptions,
60 ) -> impl Future<Output = Result<DownloadFileResult, ProviderError>> + Send {
61 let _ = options;
62 std::future::ready(Err(ProviderError::unsupported("download_file")))
63 }
64
65 fn supports_delete_file(&self) -> bool {
67 false
68 }
69
70 fn delete_file(
72 &self,
73 options: FileReferenceOptions,
74 ) -> impl Future<Output = Result<DeleteFileResult, ProviderError>> + Send {
75 let _ = options;
76 std::future::ready(Err(ProviderError::unsupported("delete_file")))
77 }
78}
79
80pub enum UploadData {
82 Bytes(Bytes),
84 Text(String),
86 Stream(BoxStream<'static, Result<Bytes, ProviderError>>),
88}
89
90impl std::fmt::Debug for UploadData {
91 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92 match self {
93 Self::Bytes(bytes) => f.debug_tuple("Bytes").field(&bytes.len()).finish(),
94 Self::Text(text) => f.debug_tuple("Text").field(&text.len()).finish(),
95 Self::Stream(_) => f.write_str("Stream(<stream>)"),
96 }
97 }
98}
99
100impl From<Bytes> for UploadData {
101 fn from(bytes: Bytes) -> Self {
102 Self::Bytes(bytes)
103 }
104}
105
106impl From<Vec<u8>> for UploadData {
107 fn from(bytes: Vec<u8>) -> Self {
108 Self::Bytes(Bytes::from(bytes))
109 }
110}
111
112impl From<String> for UploadData {
113 fn from(text: String) -> Self {
114 Self::Text(text)
115 }
116}
117
118#[derive(Debug)]
120pub struct UploadFileOptions {
121 pub data: UploadData,
123 pub media_type: MediaType,
125 pub filename: Option<String>,
127 pub headers: Headers,
129 pub provider_options: ProviderOptions,
131 pub cancellation: CancellationToken,
133}
134
135impl UploadFileOptions {
136 #[must_use]
138 pub fn new(data: impl Into<UploadData>, media_type: impl Into<MediaType>) -> Self {
139 Self {
140 data: data.into(),
141 media_type: media_type.into(),
142 filename: None,
143 headers: Headers::new(),
144 provider_options: ProviderOptions::new(),
145 cancellation: CancellationToken::new(),
146 }
147 }
148}
149
150#[derive(Debug, Clone)]
152pub struct FileReferenceOptions {
153 pub file: ProviderReference,
155 pub headers: Headers,
157 pub provider_options: ProviderOptions,
159 pub cancellation: CancellationToken,
161}
162
163impl FileReferenceOptions {
164 #[must_use]
166 pub fn new(file: ProviderReference) -> Self {
167 Self {
168 file,
169 headers: Headers::new(),
170 provider_options: ProviderOptions::new(),
171 cancellation: CancellationToken::new(),
172 }
173 }
174}
175
176#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
178pub struct UploadFileResult {
179 pub provider_reference: ProviderReference,
181 #[serde(default, skip_serializing_if = "Option::is_none")]
183 pub media_type: Option<MediaType>,
184 #[serde(default, skip_serializing_if = "Option::is_none")]
186 pub filename: Option<String>,
187 #[serde(default, skip_serializing_if = "Option::is_none")]
189 pub byte_size: Option<u64>,
190 #[serde(default, skip_serializing_if = "Option::is_none")]
192 pub created_at: Option<DateTime<Utc>>,
193 #[serde(default, skip_serializing_if = "Option::is_none")]
195 pub expires_at: Option<DateTime<Utc>>,
196 #[serde(default, skip_serializing_if = "Option::is_none")]
198 pub provider_metadata: Option<ProviderMetadata>,
199 #[serde(default)]
201 pub warnings: Vec<Warning>,
202}
203
204pub type FileMetadataResult = UploadFileResult;
206
207pub struct DownloadFileResult {
209 pub content: BoxStream<'static, Result<Bytes, ProviderError>>,
211 pub media_type: Option<MediaType>,
213 pub provider_metadata: Option<ProviderMetadata>,
215 pub warnings: Vec<Warning>,
217}
218
219impl std::fmt::Debug for DownloadFileResult {
220 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
221 f.debug_struct("DownloadFileResult")
222 .field("content", &"<stream>")
223 .field("media_type", &self.media_type)
224 .field("provider_metadata", &self.provider_metadata)
225 .field("warnings", &self.warnings)
226 .finish()
227 }
228}
229
230#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
232pub struct DeleteFileResult {
233 pub provider_reference: ProviderReference,
235 pub deleted: bool,
237 #[serde(default, skip_serializing_if = "Option::is_none")]
239 pub provider_metadata: Option<ProviderMetadata>,
240 #[serde(default)]
242 pub warnings: Vec<Warning>,
243}