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};
10
11#[derive(Clone)]
16pub struct PounceTask {
17 pub(crate) direction: Direction,
19 pub(crate) file_name: String,
21 pub(crate) file_path: PathBuf,
23 pub(crate) total_size: u64,
25 pub(crate) chunk_size: u64,
27 pub(crate) url: String,
29 pub(crate) method: Method,
31 pub(crate) headers: HeaderMap,
33 pub(crate) client_file_sign: Option<String>,
37 pub(crate) breakpoint_upload: Option<Arc<dyn BreakpointUpload + Send + Sync>>,
39 pub(crate) breakpoint_download: Option<Arc<dyn BreakpointDownload + Send + Sync>>,
41 pub(crate) breakpoint_download_http: Option<BreakpointDownloadHttpConfig>,
43 pub(crate) max_chunk_retries: u32,
47}
48
49impl fmt::Debug for PounceTask {
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 f.debug_struct("PounceTask")
52 .field("direction", &self.direction)
53 .field("file_name", &self.file_name)
54 .field("file_path", &self.file_path)
55 .field("total_size", &self.total_size)
56 .field("chunk_size", &self.chunk_size)
57 .field("url", &self.url)
58 .field("method", &self.method)
59 .field("headers", &self.headers)
60 .field("client_file_sign", &self.client_file_sign)
61 .field(
62 "breakpoint_upload",
63 &self
64 .breakpoint_upload
65 .as_ref()
66 .map(|_| "Arc<dyn BreakpointUpload + Send + Sync>"),
67 )
68 .field(
69 "breakpoint_download",
70 &self
71 .breakpoint_download
72 .as_ref()
73 .map(|_| "Arc<dyn BreakpointDownload + Send + Sync>"),
74 )
75 .field("breakpoint_download_http", &self.breakpoint_download_http)
76 .field("max_chunk_retries", &self.max_chunk_retries)
77 .finish()
78 }
79}
80
81impl PounceTask {
82 pub const DEFAULT_MAX_CHUNK_RETRIES: u32 = 3;
84
85 pub(crate) fn normalized_chunk_size(chunk_size: u64) -> u64 {
89 if chunk_size == 0 {
90 1024 * 1024
91 } else {
92 chunk_size
93 }
94 }
95
96 pub(crate) fn normalized_max_chunk_retries(max_chunk_retries: u32) -> u32 {
101 max_chunk_retries
102 }
103
104 pub(crate) fn is_empty(&self) -> bool {
108 self.file_path.as_os_str().is_empty()
109 || self.file_name.is_empty()
110 || self.url.is_empty()
111 || match self.direction {
112 Direction::Upload => self.total_size == 0,
113 Direction::Download => false,
114 }
115 }
116}