rskit_storage/store/upload.rs
1//! Upload request options and progress reporting for [`FileStore`](super::FileStore) uploads.
2
3use std::collections::HashMap;
4use std::sync::Arc;
5
6/// Upload progress report.
7pub struct UploadProgress {
8 /// Bytes sent so far.
9 pub bytes_sent: u64,
10 /// Total bytes to send (if known).
11 pub total_bytes: Option<u64>,
12 /// Completion percentage (if total is known).
13 pub percent: Option<f32>,
14}
15
16/// Callback for receiving upload progress updates.
17pub type ProgressCallback = Arc<dyn Fn(UploadProgress) + Send + Sync>;
18
19/// Options describing how a file is stored during an upload.
20///
21/// Groups the content type, user metadata, and optional progress callback so a
22/// single `upload(source, key, options)` call replaces a run of positional
23/// arguments. Build with [`UploadOptions::new`] and the `with_*` methods, or
24/// construct the struct directly.
25#[derive(Clone, Default)]
26pub struct UploadOptions {
27 /// MIME content type; falls back to the store default when absent.
28 pub content_type: Option<String>,
29 /// User metadata stored alongside the file.
30 pub metadata: HashMap<String, String>,
31 /// Progress callback invoked as bytes are written, for backends that report progress.
32 pub progress: Option<ProgressCallback>,
33}
34
35impl UploadOptions {
36 /// Create empty upload options that use the store defaults.
37 #[must_use]
38 pub fn new() -> Self {
39 Self::default()
40 }
41
42 /// Set the MIME content type for the uploaded file.
43 #[must_use]
44 pub fn with_content_type(mut self, content_type: impl Into<String>) -> Self {
45 self.content_type = Some(content_type.into());
46 self
47 }
48
49 /// Attach user metadata stored alongside the file.
50 #[must_use]
51 pub fn with_metadata(mut self, metadata: HashMap<String, String>) -> Self {
52 self.metadata = metadata;
53 self
54 }
55
56 /// Attach a progress callback invoked as bytes are written.
57 #[must_use]
58 pub fn with_progress(mut self, progress: ProgressCallback) -> Self {
59 self.progress = Some(progress);
60 self
61 }
62
63 /// Borrow the content type as a string slice, when set.
64 #[must_use]
65 pub fn content_type(&self) -> Option<&str> {
66 self.content_type.as_deref()
67 }
68}