1use baidu_netdisk_sdk::BaiduNetDiskClient;
10use log::info;
11use std::io::{self, BufRead};
12use std::time::{Duration, Instant};
13
14#[tokio::main]
15async fn main() -> Result<(), Box<dyn std::error::Error>> {
16 env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
18
19 let client = BaiduNetDiskClient::builder().build()?;
21 info!("Client created successfully");
22
23 client.load_token_from_env()?;
25 info!("Token loaded successfully");
26
27 println!("=== Baidu NetDisk Download Test ===");
28 println!("Enter the remote file path to download (e.g., /upload/test.txt):");
29
30 let stdin = io::stdin();
31 let mut reader = stdin.lock();
32 let mut input = String::new();
33 reader.read_line(&mut input)?;
34 let remote_path = input.trim();
35
36 if remote_path.is_empty() {
37 eprintln!("Error: File path cannot be empty");
38 return Ok(());
39 }
40
41 println!("\n--- Step 1: Get file info (to obtain fs_id) ---");
43 println!("Press Enter to continue...");
44 reader.read_line(&mut String::new())?;
45
46 let file_info = client.file().get_file_info(remote_path).await?;
47 let file_size = file_info.size.unwrap_or(0);
48 let fs_id = file_info.fs_id.ok_or_else(|| "File has no fs_id")?;
49 let file_meta = client.file().get_file_meta(fs_id).await?;
50
51 println!("File Info:");
52 println!(" Name: {}", file_info.name);
53 println!(" Path: {}", file_info.path);
54 println!(
55 " Size: {} bytes ({:.2} MB)",
56 file_size,
57 file_size as f64 / (1024.0 * 1024.0)
58 );
59 println!(" FS ID: {:?}", file_info.fs_id);
60
61 println!("\n--- Step 2: Single-threaded download ---");
63 if file_size > 50 * 1024 * 1024 {
64 println!(
65 "File size {} bytes exceeds 50MB, skipping single-threaded download...",
66 file_size
67 );
68 } else {
69 println!("Press Enter to continue...");
70 reader.read_line(&mut String::new())?;
71
72 let single_save_path = format!("./download_single_{}", file_info.name);
73 let start_time = Instant::now();
74
75 match client
76 .download()
77 .download_single(remote_path, &single_save_path)
78 .await
79 {
80 Ok(_) => {
81 let duration = start_time.elapsed();
82 print_download_stats("Single-threaded", file_size, duration);
83 println!("Single-threaded download successful: {}", single_save_path);
84 }
85 Err(e) => eprintln!("Single-threaded download failed: {}", e),
86 }
87 }
88
89 println!("\n--- Step 3: Parallel download (Producer-Consumer queue-based) ---");
91 println!("Press Enter to continue...");
92 reader.read_line(&mut String::new())?;
93
94 let parallel_save_path = format!("./download_parallel_{}", file_info.name);
95 let start_time = Instant::now();
96
97 match client
98 .download()
99 .download_parallel_multi_threaded(&file_meta, ¶llel_save_path, Some(12))
100 .await
101 {
102 Ok(_) => {
103 let duration = start_time.elapsed();
104 print_download_stats("Parallel (Producer-Consumer)", file_size, duration);
105 println!("Parallel download successful: {}", parallel_save_path);
106 }
107 Err(e) => eprintln!("Parallel download failed: {}", e),
108 }
109
110 println!("\n--- Step 4: Auto download (recommended) ---");
112 println!("Press Enter to continue...");
113 reader.read_line(&mut String::new())?;
114
115 let auto_save_path = format!("./download_auto_{}", file_info.name);
116 let start_time = Instant::now();
117
118 match client
119 .download()
120 .auto_download(remote_path, &auto_save_path)
121 .await
122 {
123 Ok(_) => {
124 let duration = start_time.elapsed();
125 print_download_stats("Auto download", file_size, duration);
126 println!("Auto download successful: {}", auto_save_path);
127 }
128 Err(e) => eprintln!("Auto download failed: {}", e),
129 }
130
131 println!("\n=== Download test completed ===");
132
133 Ok(())
134}
135
136fn print_download_stats(method: &str, file_size: u64, duration: Duration) {
138 let seconds = duration.as_secs_f64();
139 let mb_per_sec = if seconds > 0.0 {
140 (file_size as f64 / (1024.0 * 1024.0)) / seconds
141 } else {
142 0.0
143 };
144
145 println!("{} Download Stats:", method);
146 println!(" Duration: {:.2} seconds", seconds);
147 println!(" Speed: {:.2} MB/s", mb_per_sec);
148}