1use std::fmt;
2use std::path::PathBuf;
3use std::sync::Arc;
4
5use reqwest::header::HeaderMap;
6use reqwest::Method;
7
8use crate::direction::Direction;
9use crate::http_breakpoint::{BreakpointDownload, BreakpointDownloadHttpConfig, BreakpointUpload};
10use crate::upload_source::UploadSource;
11
12#[derive(Clone)]
17pub struct PounceTask {
18 pub(crate) direction: Direction,
20 pub(crate) file_name: String,
22 pub(crate) file_path: PathBuf,
24 pub(crate) upload_source: Option<UploadSource>,
26 pub(crate) total_size: u64,
28 pub(crate) chunk_size: u64,
30 pub(crate) url: String,
32 pub(crate) method: Method,
34 pub(crate) headers: HeaderMap,
36 pub(crate) client_file_sign: Option<String>,
40 pub(crate) breakpoint_upload: Option<Arc<dyn BreakpointUpload + Send + Sync>>,
42 pub(crate) breakpoint_download: Option<Arc<dyn BreakpointDownload + Send + Sync>>,
44 pub(crate) breakpoint_download_http: Option<BreakpointDownloadHttpConfig>,
46 pub(crate) max_chunk_retries: u32,
50 pub(crate) max_upload_prepare_retries: u32,
54}
55
56impl fmt::Debug for PounceTask {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 f.debug_struct("PounceTask")
59 .field("direction", &self.direction)
60 .field("file_name", &self.file_name)
61 .field("file_path", &self.file_path)
62 .field("upload_source", &self.upload_source)
63 .field("total_size", &self.total_size)
64 .field("chunk_size", &self.chunk_size)
65 .field("url", &self.url)
66 .field("method", &self.method)
67 .field("headers", &self.headers)
68 .field("client_file_sign", &self.client_file_sign)
69 .field(
70 "breakpoint_upload",
71 &self
72 .breakpoint_upload
73 .as_ref()
74 .map(|_| "Arc<dyn BreakpointUpload + Send + Sync>"),
75 )
76 .field(
77 "breakpoint_download",
78 &self
79 .breakpoint_download
80 .as_ref()
81 .map(|_| "Arc<dyn BreakpointDownload + Send + Sync>"),
82 )
83 .field("breakpoint_download_http", &self.breakpoint_download_http)
84 .field("max_chunk_retries", &self.max_chunk_retries)
85 .field(
86 "max_upload_prepare_retries",
87 &self.max_upload_prepare_retries,
88 )
89 .finish()
90 }
91}
92
93impl PounceTask {
94 pub const DEFAULT_MAX_CHUNK_RETRIES: u32 = 3;
96
97 pub const DEFAULT_MAX_UPLOAD_PREPARE_RETRIES: u32 = 3;
99
100 pub(crate) fn normalized_chunk_size(chunk_size: u64) -> u64 {
104 if chunk_size == 0 {
105 1024 * 1024
106 } else {
107 chunk_size
108 }
109 }
110
111 pub(crate) fn normalized_max_chunk_retries(max_chunk_retries: u32) -> u32 {
116 max_chunk_retries
117 }
118
119 pub(crate) fn normalized_max_upload_prepare_retries(max_upload_prepare_retries: u32) -> u32 {
121 max_upload_prepare_retries
122 }
123
124 pub(crate) fn is_empty(&self) -> bool {
128 self.file_name.is_empty()
129 || self.url.is_empty()
130 || match self.direction {
131 Direction::Upload => self.total_size == 0 || self.upload_source.is_none(),
132 Direction::Download => self.file_path.as_os_str().is_empty(),
133 }
134 }
135}