diff --git a/Cargo.lock b/Cargo.lock index 30f7b06..ecc5a25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -185,23 +185,21 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android-activity" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" +checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd" dependencies = [ "android-properties", "bitflags 2.11.0", "cc", - "cesu8", - "jni", - "jni-sys", + "jni 0.22.4", "libc", "log", "ndk", "ndk-context", "ndk-sys", "num_enum", - "thiserror 1.0.69", + "thiserror 2.0.18", ] [[package]] @@ -907,9 +905,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.57" +version = "1.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" +checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" dependencies = [ "find-msvc-tools", "jobserver", @@ -1007,9 +1005,9 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" dependencies = [ "cc", ] @@ -1623,6 +1621,8 @@ dependencies = [ [[package]] name = "fast-down-ffi" version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af8a9ad3c30e37953218ae2fdb47182abf8ab7f46297f64f70433a073ffb4698" dependencies = [ "crossfire", "fast-down", @@ -1647,7 +1647,7 @@ dependencies = [ "dashmap", "dirs", "fast-down-ffi", - "fs4", + "file_alloc", "gtk", "i-slint-backend-winit", "image", @@ -1768,6 +1768,17 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "file_alloc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c557211ab46e850d1e03bb3e831de58dbbe232e21141d33f5d92bc51ed933a" +dependencies = [ + "rustix 1.1.4", + "tokio", + "windows-sys 0.61.2", +] + [[package]] name = "filetime" version = "0.2.27" @@ -1910,17 +1921,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs4" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8640e34b88f7652208ce9e88b1a37a2ae95227d84abec377ccd3c5cfeb141ed4" -dependencies = [ - "rustix 1.1.4", - "tokio", - "windows-sys 0.59.0", -] - [[package]] name = "fs_extra" version = "1.3.0" @@ -3178,9 +3178,9 @@ checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +checksum = "d8e7418f59cc01c88316161279a7f665217ae316b388e58a0d10e29f54f1e5eb" dependencies = [ "memchr", "serde", @@ -3238,18 +3238,70 @@ dependencies = [ "cesu8", "cfg-if", "combine", - "jni-sys", + "jni-sys 0.3.1", "log", "thiserror 1.0.69", "walkdir", "windows-sys 0.45.0", ] +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys 0.4.1", + "log", + "simd_cesu8", + "thiserror 2.0.18", + "walkdir", + "windows-link 0.2.1", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.117", +] + [[package]] name = "jni-sys" -version = "0.3.0" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.117", +] [[package]] name = "jobserver" @@ -3406,9 +3458,9 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" +checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08" dependencies = [ "bitflags 2.11.0", "libc", @@ -3666,9 +3718,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "wasi", @@ -3719,7 +3771,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ "bitflags 2.11.0", - "jni-sys", + "jni-sys 0.3.1", "log", "ndk-sys", "num_enum", @@ -3739,7 +3791,7 @@ version = "0.6.0+11769913" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" dependencies = [ - "jni-sys", + "jni-sys 0.3.1", ] [[package]] @@ -3819,9 +3871,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" [[package]] name = "num-derive" @@ -4694,7 +4746,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.25.5+spec-1.1.0", + "toml_edit 0.25.8+spec-1.1.0", ] [[package]] @@ -4751,9 +4803,9 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14104c5a24d9bcf7eb2c24753e0f49fe14555d8bd565ea3d38e4b4303267259d" +checksum = "7c3a14896dfa883796f1cb410461aef38810ea05f2b2c33c5aded3649095fdad" dependencies = [ "bitflags 2.11.0", "getopts", @@ -5342,7 +5394,7 @@ checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" dependencies = [ "core-foundation 0.10.1", "core-foundation-sys", - "jni", + "jni 0.21.1", "log", "once_cell", "rustls", @@ -5549,9 +5601,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +checksum = "876ac351060d4f882bb1032b6369eb0aef79ad9df1ea8bc404874d8cc3d0cd98" dependencies = [ "serde_core", ] @@ -5595,9 +5647,19 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" + +[[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] [[package]] name = "simd_helpers" @@ -5608,6 +5670,12 @@ dependencies = [ "quote", ] +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "simplecss" version = "0.2.2" @@ -6324,7 +6392,7 @@ checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ "indexmap", "serde_core", - "serde_spanned 1.0.4", + "serde_spanned 1.1.0", "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", @@ -6333,14 +6401,14 @@ dependencies = [ [[package]] name = "toml" -version = "1.0.7+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd28d57d8a6f6e458bc0b8784f8fdcc4b99a437936056fa122cb234f18656a96" +checksum = "f8195ca05e4eb728f4ba94f3e3291661320af739c4e43779cbdfae82ab239fcc" dependencies = [ "indexmap", "serde_core", - "serde_spanned 1.0.4", - "toml_datetime 1.0.1+spec-1.1.0", + "serde_spanned 1.1.0", + "toml_datetime 1.1.0+spec-1.1.0", "toml_parser", "toml_writer", "winnow 1.0.0", @@ -6366,9 +6434,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "1.0.1+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b320e741db58cac564e26c607d3cc1fdc4a88fd36c879568c07856ed83ff3e9" +checksum = "97251a7c317e03ad83774a8752a7e81fb6067740609f75ea2b585b569a59198f" dependencies = [ "serde_core", ] @@ -6412,30 +6480,30 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.5+spec-1.1.0" +version = "0.25.8+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca1a40644a28bce036923f6a431df0b34236949d111cc07cb6dca830c9ef2e1" +checksum = "16bff38f1d86c47f9ff0647e6838d7bb362522bdf44006c7068c2b1e606f1f3c" dependencies = [ "indexmap", - "toml_datetime 1.0.1+spec-1.1.0", + "toml_datetime 1.1.0+spec-1.1.0", "toml_parser", "winnow 1.0.0", ] [[package]] name = "toml_parser" -version = "1.0.10+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420" +checksum = "2334f11ee363607eb04df9b8fc8a13ca1715a72ba8662a26ac285c98aabb4011" dependencies = [ "winnow 1.0.0", ] [[package]] name = "toml_writer" -version = "1.0.7+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17aaa1c6e3dc22b1da4b6bba97d066e354c7945cac2f7852d4e4e7ca7a6b56d" +checksum = "d282ade6016312faf3e41e57ebbba0c073e4056dab1232ab1cb624199648f8ed" [[package]] name = "tower" @@ -6696,9 +6764,9 @@ checksum = "383ad40bb927465ec0ce7720e033cb4ca06912855fc35db31b5755d0de75b1ee" [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" [[package]] name = "unicode-vo" @@ -6784,9 +6852,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.22.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ "js-sys", "serde_core", @@ -7873,7 +7941,7 @@ version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0986a8b1d586b7d3e4fe3d9ea39fb451ae22869dcea4aa109d287a374d866087" dependencies = [ - "toml 1.0.7+spec-1.1.0", + "toml 1.1.0+spec-1.1.0", "version_check", ] @@ -8375,9 +8443,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7a1c0af6e5d8d1363f4994b7a091ccf963d8b694f7da5b0b9cceb82da2c0a6" +checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" dependencies = [ "zune-core", ] diff --git a/Cargo.toml b/Cargo.toml index 5cc1aa4..2a13140 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,9 +25,8 @@ color-eyre = "0.6.5" crossfire = "3.1.7" dashmap = { version = "6.1.0", features = ["serde"] } dirs = "6.0.0" -# fast-down-ffi = { version = "0.2.0", features = ["file", "reqwest-tls", "serde"] } -fast-down-ffi = { path = "../ffi/", features = ["file", "reqwest-tls", "serde"] } -fs4 = { version = "0.13.1", features = ["tokio"] } +fast-down-ffi = { version = "0.2.1", features = ["file", "reqwest-tls", "serde"] } +# fast-down-ffi = { path = "../ffi/", features = ["file", "reqwest-tls", "serde"] } i-slint-backend-winit = "1.15.1" image = "0.25.10" interprocess = { version = "2.4.0", features = ["tokio"] } @@ -48,6 +47,7 @@ tracing-appender = "0.2.4" tracing-subscriber = { version = "0.3.23", features = ["env-filter"] } tray-icon = "0.21.3" url = { version = "2.5.8", features = ["serde"] } +file_alloc = "0.1.2" [build-dependencies] slint-build = "1.15.1" diff --git a/src/core/download.rs b/src/core/download.rs index c27f8b9..f156deb 100644 --- a/src/core/download.rs +++ b/src/core/download.rs @@ -5,6 +5,7 @@ use crate::{ utils::{auto_ext, sanitize}, }; use fast_down_ffi::{Event, Total, create_channel, prefetch, unique_path::gen_unique_path}; +use file_alloc::FileAlloc; use parking_lot::Mutex; use slint::SharedString; use std::{ @@ -12,7 +13,7 @@ use std::{ sync::Arc, time::{Duration, Instant}, }; -use tokio::fs; +use tokio::fs::{self, OpenOptions}; use tokio_util::sync::CancellationToken; use tracing::{error, info, warn}; use url::Url; @@ -57,6 +58,7 @@ pub async fn download( .map(|e| e.progress.clone()) .unwrap_or_default(), )); + let pre_allocate = config.pre_allocate; let download_config = fast_down_ffi::Config { retry_times: config.retry_times, threads: config.threads, @@ -115,6 +117,15 @@ pub async fn download( ) }; on_event(DownloadEvent::Info(Box::new(entry))); + if pre_allocate && total_size > 1024 * 1024 && progress.lock().is_empty() { + let mut file = OpenOptions::new() + .write(true) + .create(true) + .truncate(false) + .open(&save_path) + .await?; + file.allocate(total_size).await?; + } Ok::<_, color_eyre::Report>(( task, save_path, diff --git a/src/main.rs b/src/main.rs index c10017f..b662ea9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,7 @@ use fast_down_gui::{ ui::*, utils::{LogErr, show_task_dialog}, }; +use file_alloc::init_fast_alloc; use rfd::FileDialog; use slint::{Model, ModelRc, ToSharedString, VecModel}; use std::{collections::HashSet, rc::Rc, sync::Arc}; @@ -81,6 +82,7 @@ async fn main() -> color_eyre::Result<()> { let _ = check_ipc_and_wake().await.log_err("检查 ipc 通道错误"); let _ = auto_register().log_err("写入浏览器扩展通信配置失败"); let ui = MainWindow::new()?; + init_fast_alloc(); let db = Database::new().await; let task_set = TaskSet::new(db.inner.general_config.lock().max_concurrency); let auto = get_auto_start() diff --git a/src/persist/config.rs b/src/persist/config.rs index edb8fb2..4b606c2 100644 --- a/src/persist/config.rs +++ b/src/persist/config.rs @@ -22,6 +22,7 @@ pub struct DownloadConfig { pub write_method: WriteMethod, pub retry_times: usize, pub chunk_window: u64, + pub pre_allocate: bool, } impl Default for DownloadConfig { @@ -43,6 +44,7 @@ impl Default for DownloadConfig { write_method: WriteMethod::Mmap, retry_times: 3, chunk_window: 8 * 1024, + pre_allocate: false, } } } @@ -84,6 +86,7 @@ impl DownloadConfig { write_queue_cap: self.write_queue_cap as i32, retry_times: self.retry_times as i32, chunk_window: self.chunk_window as i32, + pre_allocate: self.pre_allocate, } } } @@ -119,6 +122,7 @@ impl From<&crate::ui::DownloadConfig> for DownloadConfig { }, retry_times: value.retry_times as usize, chunk_window: value.chunk_window as u64, + pre_allocate: value.pre_allocate, } } } diff --git a/src/persist/loader/mod.rs b/src/persist/loader/mod.rs index 75b18c4..0415617 100644 --- a/src/persist/loader/mod.rs +++ b/src/persist/loader/mod.rs @@ -2,10 +2,11 @@ mod v1; mod v2; mod v3; mod v4; +mod v5; use crate::persist::{ DatabaseInner, - loader::{v1::V1Loader, v2::V2Loader, v3::V3Loader, v4::V4Loader}, + loader::{v1::V1Loader, v2::V2Loader, v3::V3Loader, v4::V4Loader, v5::V5Loader}, }; pub trait Loader { @@ -17,8 +18,9 @@ pub struct BoxLoader; impl Loader for BoxLoader { fn load(&self, bytes: &[u8]) -> Option { - V4Loader + V5Loader .load(bytes) + .or_else(|| V4Loader.load(bytes)) .or_else(|| V3Loader.load(bytes)) .or_else(|| V2Loader.load(bytes)) .or_else(|| V1Loader.load(bytes)) diff --git a/src/persist/loader/v1.rs b/src/persist/loader/v1.rs index d04099f..a6fc33a 100644 --- a/src/persist/loader/v1.rs +++ b/src/persist/loader/v1.rs @@ -50,6 +50,7 @@ impl From for crate::persist::DownloadConfig { local_address: c.local_address, max_speculative: c.max_speculative, write_method: c.write_method, + pre_allocate: false, } } } diff --git a/src/persist/loader/v2.rs b/src/persist/loader/v2.rs index 4341831..79d73b1 100644 --- a/src/persist/loader/v2.rs +++ b/src/persist/loader/v2.rs @@ -48,6 +48,7 @@ impl From for crate::persist::DownloadConfig { local_address: c.local_address, max_speculative: c.max_speculative, write_method: c.write_method, + pre_allocate: false, } } } diff --git a/src/persist/loader/v3.rs b/src/persist/loader/v3.rs index 1dc0ec5..2f0e287 100644 --- a/src/persist/loader/v3.rs +++ b/src/persist/loader/v3.rs @@ -53,6 +53,7 @@ impl From for crate::persist::DownloadConfig { local_address: c.local_address, max_speculative: c.max_speculative, write_method: c.write_method, + pre_allocate: false, } } } diff --git a/src/persist/loader/v4.rs b/src/persist/loader/v4.rs index b30d02e..9555dc9 100644 --- a/src/persist/loader/v4.rs +++ b/src/persist/loader/v4.rs @@ -54,6 +54,7 @@ impl From for crate::persist::DownloadConfig { local_address: c.local_address, max_speculative: c.max_speculative, write_method: c.write_method, + pre_allocate: false, } } } diff --git a/src/persist/loader/v5.rs b/src/persist/loader/v5.rs new file mode 100644 index 0000000..10feb0d --- /dev/null +++ b/src/persist/loader/v5.rs @@ -0,0 +1,146 @@ +use crate::persist::loader::Loader; +use dashmap::DashMap; +use fast_down_ffi::{FileId, ProgressEntry, Proxy, WriteMethod}; +use parking_lot::Mutex; +use serde::Deserialize; +use std::{ + collections::HashMap, net::IpAddr, path::PathBuf, sync::atomic::AtomicI32, time::Duration, +}; +use url::Url; + +#[derive(Deserialize, Debug)] +pub struct DownloadConfig { + pub save_dir: PathBuf, + pub threads: usize, + pub proxy: Proxy, + pub headers: HashMap, + pub min_chunk_size: u64, + pub write_buffer_size: usize, + pub write_queue_cap: usize, + pub retry_gap: Duration, + pub pull_timeout: Duration, + pub accept_invalid_certs: bool, + pub accept_invalid_hostnames: bool, + pub local_address: Vec, + pub max_speculative: usize, + pub write_method: WriteMethod, + pub retry_times: usize, + pub chunk_window: u64, + pub pre_allocate: bool, +} + +#[derive(Deserialize, Debug)] +pub struct GeneralConfig { + pub max_concurrency: usize, + pub auto_start: bool, + pub exit_after_download: bool, +} + +impl From for crate::persist::DownloadConfig { + fn from(c: DownloadConfig) -> Self { + Self { + proxy: c.proxy, + retry_times: c.retry_times, + chunk_window: c.chunk_window, + save_dir: c.save_dir, + threads: c.threads, + headers: c.headers, + min_chunk_size: c.min_chunk_size, + write_buffer_size: c.write_buffer_size, + write_queue_cap: c.write_queue_cap, + retry_gap: c.retry_gap, + pull_timeout: c.pull_timeout, + accept_invalid_certs: c.accept_invalid_certs, + accept_invalid_hostnames: c.accept_invalid_hostnames, + local_address: c.local_address, + max_speculative: c.max_speculative, + write_method: c.write_method, + pre_allocate: c.pre_allocate, + } + } +} + +impl From for crate::persist::GeneralConfig { + fn from(c: GeneralConfig) -> Self { + Self { + max_concurrency: c.max_concurrency, + auto_start: c.auto_start, + exit_after_download: c.exit_after_download, + } + } +} + +#[derive(Deserialize, Debug)] +pub struct DatabaseEntry { + pub file_name: String, + pub file_path: PathBuf, + pub file_size: u64, + pub file_id: FileId, + pub progress: Vec, + pub elapsed: Duration, + pub url: Url, + pub config: DownloadConfig, + pub status: Status, +} + +impl From for crate::persist::DatabaseEntry { + fn from(e: DatabaseEntry) -> Self { + Self { + file_name: e.file_name, + file_path: e.file_path, + file_size: e.file_size, + file_id: e.file_id, + progress: e.progress, + elapsed: e.elapsed, + url: e.url, + config: e.config.into(), + status: e.status.into(), + } + } +} + +#[derive(Deserialize, Debug)] +pub enum Status { + Completed, + Error, + Paused, +} + +impl From for crate::persist::Status { + fn from(value: Status) -> Self { + match value { + Status::Completed => crate::persist::Status::Completed, + Status::Error => crate::persist::Status::Error, + Status::Paused => crate::persist::Status::Paused, + } + } +} + +#[derive(Deserialize, Debug)] +pub struct DatabaseInner { + pub data: DashMap, + pub download_config: Mutex, + pub general_config: Mutex, + pub max_gid: AtomicI32, +} + +impl From for crate::persist::DatabaseInner { + fn from(db: DatabaseInner) -> Self { + Self { + data: db.data.into_iter().map(|(k, v)| (k, v.into())).collect(), + download_config: Mutex::new(db.download_config.into_inner().into()), + general_config: Mutex::new(db.general_config.into_inner().into()), + max_gid: db.max_gid, + } + } +} + +#[derive(Debug, Clone)] +pub struct V5Loader; + +impl Loader for V5Loader { + fn load(&self, bytes: &[u8]) -> Option { + let db: DatabaseInner = bitcode::deserialize(bytes).ok()?; + Some(db.into()) + } +} diff --git a/ui/settings.slint b/ui/settings.slint index 5bfda90..b7abe51 100644 --- a/ui/settings.slint +++ b/ui/settings.slint @@ -31,6 +31,7 @@ export struct DownloadConfig { write_method: int, retry_times: int, chunk_window: int, + pre_allocate: bool, } export struct GeneralConfig { max_concurrency: int, @@ -277,6 +278,16 @@ export component Settings inherits VerticalLayout { } } + HorizontalBox { + padding: 0px; + + CheckBox { + text: "文件预分配"; + horizontal-stretch: 1; + checked <=> download_config.pre-allocate; + } + } + Text { text: "写入方法"; }