dw-rs 0.2.0

A blazingly fast, parallel download accelerator written in Rust.
Documentation
use clap::Parser;
use dw_rs::config::DownloadConfig;
use dw_rs::downloader::DownloadOptimizer;
use dw_rs::utils;
use std::process;
use std::time::Duration;

#[derive(Parser)]
#[command(
    author,
    version,
    about = "A blazingly fast download accelerator, written in Rust."
)]
struct Args {
    url: String,

    #[arg(short, long)]
    output: Option<String>,

    #[arg(short = 'c', long, default_value = "8")]
    connections: usize,

    #[arg(short = 'b', long, default_value = "4096")]
    buffer_size: usize,

    #[arg(long, default_value = "4")]
    piece_size: u64,

    #[arg(long, default_value = "1")]
    min_chunk: u64,

    #[arg(long, default_value = "5")]
    retries: u32,

    #[arg(long, default_value = "60")]
    timeout: u64,

    #[arg(short, long)]
    quiet: bool,

    #[arg(long, hide = true)]
    adaptive: bool,
}

const GITHUB_ISSUES_URL: &str = "https://github.com/amirhosseinghanipour/dw/issues";

#[tokio::main]
async fn main() {
    let args = Args::parse();
    let config = DownloadConfig {
        max_connections: args.connections,
        min_chunk_size: args.min_chunk * 1024 * 1024,
        piece_size: args.piece_size * 1024 * 1024,
        write_buffer: args.buffer_size * 1024,
        max_retries: args.retries,
        piece_timeout: Duration::from_secs(args.timeout),
        connect_timeout: Duration::from_secs(15),
        quiet: args.quiet,
    };

    let optimizer = match DownloadOptimizer::new(config).await {
        Ok(optimizer) => optimizer,
        Err(e) => {
            eprintln!("Failed to initialize downloader: {e}");
            eprintln!("\nIf this issue persists, please open an issue on GitHub:");
            eprintln!("{GITHUB_ISSUES_URL}");
            process::exit(1);
        }
    };

    let filename = args.output.unwrap_or_else(|| {
        utils::extract_filename(&args.url).unwrap_or_else(|| "downloaded_file".to_string())
    });

    match optimizer.download(&args.url, &filename).await {
        Ok(_) => println!("Download saved as: {filename}"),
        Err(e) => {
            eprintln!("Download failed: {e}");
            eprintln!("\nIf you believe this is a bug, please open an issue on GitHub:");
            eprintln!("{GITHUB_ISSUES_URL}");
            process::exit(1);
        }
    }
}