1use crate::utils::parse_header_hashmap;
2use fast_down_ffi::{Proxy, WriteMethod};
3use itertools::Itertools;
4use serde::{Deserialize, Serialize};
5use slint::ToSharedString;
6use std::{collections::HashMap, net::IpAddr, path::PathBuf, time::Duration};
7
8#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
9pub struct DownloadConfig {
10 pub save_dir: PathBuf,
11 pub file_name: String,
12 pub threads: usize,
13 pub proxy: Proxy<String>,
14 pub headers: HashMap<String, String>,
15 pub min_chunk_size: u64,
16 pub write_buffer_size: usize,
17 pub write_queue_cap: usize,
18 pub retry_gap: Duration,
19 pub pull_timeout: Duration,
20 pub accept_invalid_certs: bool,
21 pub accept_invalid_hostnames: bool,
22 pub local_address: Vec<IpAddr>,
23 pub max_speculative: usize,
24 pub write_method: WriteMethod,
25 pub retry_times: usize,
26 pub chunk_window: u64,
27 pub pre_allocate: bool,
28}
29
30impl Default for DownloadConfig {
31 fn default() -> Self {
32 Self {
33 save_dir: dirs::download_dir().unwrap_or_default(),
34 file_name: String::new(),
35 threads: 32,
36 proxy: Proxy::System,
37 headers: HashMap::new(),
38 min_chunk_size: 500 * 1024,
39 write_buffer_size: 16 * 1024 * 1024,
40 write_queue_cap: 10240,
41 retry_gap: Duration::from_millis(500),
42 pull_timeout: Duration::from_secs(5),
43 accept_invalid_certs: false,
44 accept_invalid_hostnames: false,
45 local_address: Vec::new(),
46 max_speculative: 3,
47 write_method: WriteMethod::Mmap,
48 retry_times: 3,
49 chunk_window: 8 * 1024,
50 pre_allocate: false,
51 }
52 }
53}
54
55impl DownloadConfig {
56 pub fn to_ui_download_config(&self) -> crate::ui::DownloadConfig {
57 crate::ui::DownloadConfig {
58 accept_invalid_certs: self.accept_invalid_certs,
59 accept_invalid_hostnames: self.accept_invalid_hostnames,
60 headers: self
61 .headers
62 .iter()
63 .map(|(k, v)| format!("{k}: {v}"))
64 .join("\n")
65 .into(),
66 ips: self
67 .local_address
68 .iter()
69 .map(|addr| addr.to_string())
70 .join("\n")
71 .into(),
72 max_speculative: self.max_speculative as i32,
73 min_chunk_size: self.min_chunk_size as i32,
74 proxy: match self.proxy.as_deref() {
75 Proxy::No => "null",
76 Proxy::System => "",
77 Proxy::Custom(proxy) => proxy,
78 }
79 .into(),
80 pull_timeout_ms: self.pull_timeout.as_millis() as i32,
81 retry_gap_ms: self.retry_gap.as_millis() as i32,
82 save_dir: self.save_dir.to_string_lossy().as_ref().into(),
83 threads: self.threads as i32,
84 write_buffer_size: self.write_buffer_size as i32,
85 write_method: match self.write_method {
86 WriteMethod::Mmap => 0,
87 WriteMethod::Std => 1,
88 },
89 write_queue_cap: self.write_queue_cap as i32,
90 retry_times: self.retry_times as i32,
91 chunk_window: self.chunk_window as i32,
92 pre_allocate: self.pre_allocate,
93 file_name: self.file_name.to_shared_string(),
94 }
95 }
96}
97
98impl From<&crate::ui::DownloadConfig> for DownloadConfig {
99 fn from(value: &crate::ui::DownloadConfig) -> Self {
100 Self {
101 save_dir: value.save_dir.as_str().into(),
102 file_name: value.file_name.to_string(),
103 threads: value.threads as usize,
104 proxy: match value.proxy.as_str() {
105 "" => Proxy::System,
106 "null" => Proxy::No,
107 proxy => Proxy::Custom(proxy.to_string()),
108 },
109 headers: parse_header_hashmap(&value.headers),
110 min_chunk_size: value.min_chunk_size as u64,
111 write_buffer_size: value.write_buffer_size as usize,
112 write_queue_cap: value.write_queue_cap as usize,
113 retry_gap: Duration::from_millis(value.retry_gap_ms as u64),
114 pull_timeout: Duration::from_millis(value.pull_timeout_ms as u64),
115 accept_invalid_certs: value.accept_invalid_certs,
116 accept_invalid_hostnames: value.accept_invalid_hostnames,
117 local_address: value
118 .ips
119 .as_str()
120 .lines()
121 .filter_map(|line| line.trim().parse().ok())
122 .collect(),
123 max_speculative: value.max_speculative as usize,
124 write_method: match value.write_method {
125 1 => WriteMethod::Std,
126 _ => WriteMethod::Mmap,
127 },
128 retry_times: value.retry_times as usize,
129 chunk_window: value.chunk_window as u64,
130 pre_allocate: value.pre_allocate,
131 }
132 }
133}
134
135#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
136pub struct GeneralConfig {
137 pub max_concurrency: usize,
138 pub auto_start: bool,
139 pub exit_after_download: bool,
140}
141
142impl Default for GeneralConfig {
143 fn default() -> Self {
144 Self {
145 max_concurrency: 2,
146 auto_start: false,
147 exit_after_download: false,
148 }
149 }
150}
151
152impl From<&crate::ui::GeneralConfig> for GeneralConfig {
153 fn from(value: &crate::ui::GeneralConfig) -> Self {
154 Self {
155 max_concurrency: value.max_concurrency as usize,
156 auto_start: value.auto_start,
157 exit_after_download: value.exit_after_download,
158 }
159 }
160}
161
162impl GeneralConfig {
163 pub fn to_ui_general_config(&self) -> crate::ui::GeneralConfig {
164 crate::ui::GeneralConfig {
165 max_concurrency: self.max_concurrency as i32,
166 auto_start: self.auto_start,
167 exit_after_download: self.exit_after_download,
168 }
169 }
170}