Crates.io | dwldutil |
lib.rs | dwldutil |
version | 3.1.1 |
created_at | 2025-03-23 14:03:19.335829+00 |
updated_at | 2025-07-29 12:14:00.610932+00 |
description | A utility for parallel downloading |
homepage | |
repository | https://github.com/k3nder/dwldutil |
max_upload_size | |
id | 1602712 |
size | 139,890 |
Utility for downloading files in parallel.
DWLDUtil is a library for downloading multiple files in parallel using the asynchronous SMOL engine, it allows to verify the sha1 and sha512 of the files and displays a progress bar of the files.
use dwldutil::{Downloader, DLFile, DLHashes, indicator::Silent};
// Create a new downloader, with silent indicator
let dl = Downloader::<Silent>::new()
// add new file to downloader
.add_file(
DLFile::new()
// define file properties
.with_path("image.png")
.with_url("https://httpbin.org/image/png")
.with_size(8090)
.with_hashes(DLHashes::new()
.sha1("379f5137831350c900e757b39e525b9db1426d53")
)),
);
// Start download
dl.start();
examples/image.rs
to configure the downloading of multiple files at once you can use the DLStartConfig configuration, as follows
let dl = dl
.with_max_concurrent_downloads(10);
dl.start();
in order to use progress bars or indicate in some way where the download is going, you have to use flags, these flags allow you to implement events for each downloaded file, to save time, there are already two available implementations of flags:
indicatif_indicator
feature, it allows you to use indicatif to generate progress bars.use dwldutil::{Downloader, indicator::Silent}
let downloader = Downloader::<Silent>::new();
if you want to implement your own indicators, you have to create two structures, one that implements IndicatorFactory and another that implements Indicator:
use dwldutil::indicator::{Indicator, IndicateSignal, IndicatorFactory};
#[derive(Debug)]
pub struct MyIndicator;
impl IndicatorFactory for MyIndicator {
fn create_task(name: &str, size: u64) -> impl Indicator {
MyIndicatorChild
}
}
pub struct MyIndicatorChild;
impl Indicator for MyIndicatorChild {
fn effect(&mut self, position: u64) {
}
fn signal(&mut self, signal: IndicateSignal) {
match signal {
IndicateSignal::Fail(err) => {
println!("Error downloading file {}", err);
},
IndicateSignal::State(stat) => {
println!("Changing downloading state of file to {}", stat);
},
IndicateSignal::Success() => {
println!("Downloading file successfull");
}
}
}
}
// For use
let dl = Downloader::<MyIndicator>::new();
// if you have specific properties inside the factory, and you don't want to use the default ones use:
dl.with_indicator(MyIndicator {});
if you want to decompress the downloaded file, whether it is a tar.gz or a zip file, you can do it in a simple way by activating a feature, as follows
[dependencies]
dwldutil = { version = "1.0.0", features = ["decompress", "normal_zip", "gzip"] }
the decompress feature is needed by both features, the normal_zip feature implements the ZIP format and the GZIP feature implements the tar.gz format.
use dwldutil::decompress::{ Decompressor, DLDecompressionConfig, DecompressionMethod };
use dwldutil::decompress::zip::ZipDecompressor;
use dwldutil::{Downloader, DLFile, DLHashes};
use dwldutil::indicator::Silent;
// Create a new downloader
let dl = Downloader::<Silent>::new()
// add new file to downloader
.add_file(
DLFile::new()
// define file properties
.with_path("file.tar.gz")
.with_url("https://httpbin.org/zip/file.zip")
.with_size(8090)
.with_hashes(DLHashes::new()
.sha1("379f5137831350c900e757b39e525b9db1426d53")
)),
.with_decompression_config(DLDecompressionConfig::new(DecompressionMethod::Zip, "output_folder"))
);
// Start download
dl.start();
this will also delete the downloaded file after compressing, if you want to keep it you can use
DLDecompressionConfig::new(DecompressionMethod::Zip, "output_folder").with_delete_after(false)
you can use a file storage, download the files once and use symlinks to connect everything.
the ‘cas’ feature is implemented by default
use dwldutil::{cas::DLStorage, cas::DLFile};
let storage = DLStorage::new(".objects");
let file = DLFile::new()
.with_path("file.tar.gz")
.with_url("https://httpbin.org/zip/file.zip")
.with_size(8090)
.with_hashes(DLHashes::new()
.sha1("379f5137831350c900e757b39e525b9db1426d53")
)
.with_storage(storage.clone());
[!WARNING] This needs a mandatory hash, otherwise it does not work.
when this error occurs it usually indicates that the server is being redirected, this error has been fixed in version 1.0.0, please consider updating.
If you have already updated and the problem now appears as ‘Too many redirects’, you will have to increase the number of redirects allowed in DLStartConfig, as follows:
let dl = dl
.with_max_redirects(10);
dl.start();
Since the last update where openssl was changed to rustls this error can occur, it is a certification error, where an invalid certificate is used for a SNI, this can be fixed with the no_static_client
feature that creates a surf client for each download.
dwldutil = { version = "2.0.4", features = ["no_static_client"] }