Skip to main content

fast_down_gui/persist/
config.rs

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