ketcindyinstaller/worker/
downloader.rs

1use std::path::PathBuf;
2use anyhow::Result;
3use std::io::Write;
4
5pub(super) async fn download_file<F>(
6    source: url::Url,
7    destination: PathBuf,
8    mut progress_callback: F
9) -> Result<PathBuf> 
10where
11    F: FnMut(f32) + Send,
12{
13    // 指定したURLにアクセス,同時にファイルサイズを取得
14    let mut response = reqwest::get(source).await?.error_for_status()?;
15    let total_size = response.content_length();
16    let mut downloaded_size = 0f32;
17
18    // ファイル作成
19    let mut file = std::fs::File::create(&destination)?;
20
21    // レスポンスボディをファイルに書き込む
22    while let Some(chunk) = response.chunk().await? {
23        file.write_all(&chunk)?;
24        downloaded_size += chunk.len() as f32;
25
26        // ファイルサイズが取得できている場合は,進捗を計算して通知する
27        if let Some(total_size) = total_size {
28            progress_callback(downloaded_size / total_size as f32);
29        }
30    }
31
32    Ok(destination)
33}