asset_transfer/
asset_transfer.rs

1//! Asset Transfer Example
2//!
3//! Demonstrates large file transfers with chunking and verification.
4//!
5//! # Usage
6//!
7//! ```bash
8//! cargo run --example asset_transfer
9//! ```
10//!
11//! This example creates a test file, transfers it using the asset
12//! distribution system, and verifies integrity.
13
14use std::io::{self, Write};
15use std::fs::File;
16
17use fastnet::assets::{AssetServer, AssetClient, AssetConfig, AssetEvent};
18use uuid::Uuid;
19
20#[tokio::main]
21async fn main() -> io::Result<()> {
22    println!("╔════════════════════════════════════════╗");
23    println!("║    FastNet Asset Transfer Example      ║");
24    println!("╚════════════════════════════════════════╝");
25    println!();
26    
27    // Create test file
28    let test_file = "/tmp/fastnet_test_asset.bin";
29    let output_file = "/tmp/fastnet_received_asset.bin";
30    
31    println!("1. Creating test file...");
32    create_test_file(test_file, 256 * 1024)?; // 256 KB
33    println!("   Created: {} (256 KB)", test_file);
34    println!();
35    
36    // Server: Register asset
37    println!("2. Registering asset on server...");
38    let mut server = AssetServer::new(AssetConfig::default());
39    let info = server.register("test-asset", test_file).await?;
40    println!("   Name: {}", info.name);
41    println!("   Size: {} bytes", info.size);
42    println!("   Chunks: {}", info.chunk_count);
43    println!("   Hash: {:?}...", &info.hash[..8]);
44    println!();
45    
46    // Client: Request download
47    println!("3. Client requesting asset...");
48    let mut client = AssetClient::new();
49    
50    // Simulate request/response
51    let peer_id = Uuid::new_v4();
52    let (transfer_id, asset_info) = server.handle_request(peer_id, "test-asset")
53        .ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "Asset not found"))?;
54    
55    println!("   Transfer ID: {}", transfer_id);
56    client.start_download(transfer_id, asset_info.clone(), output_file)?;
57    println!();
58    
59    // Transfer chunks
60    println!("4. Transferring chunks...");
61    let mut chunks_sent = 0;
62    
63    while let Some(chunk) = server.get_next_chunk(transfer_id)? {
64        chunks_sent += 1;
65        
66        // Simulate network transfer
67        let complete = client.receive_chunk(chunk)?;
68        
69        // Print progress
70        if let Some(progress) = client.get_progress(transfer_id) {
71            print!("\r   Progress: {:.1}% ({}/{} chunks)", 
72                progress * 100.0, chunks_sent, asset_info.chunk_count);
73            io::stdout().flush()?;
74        }
75        
76        if complete {
77            println!();
78            break;
79        }
80    }
81    
82    // Process events
83    println!();
84    println!("5. Processing events...");
85    for event in client.poll_events() {
86        match event {
87            AssetEvent::Progress { received, total, .. } => {
88                println!("   Progress: {} / {} bytes", received, total);
89            }
90            AssetEvent::Completed { path, .. } => {
91                println!("   ✅ Transfer complete: {:?}", path);
92            }
93            AssetEvent::Failed { error, .. } => {
94                println!("   ❌ Transfer failed: {}", error);
95            }
96            _ => {}
97        }
98    }
99    
100    // Verify files match
101    println!();
102    println!("6. Verifying integrity...");
103    let original = std::fs::read(test_file)?;
104    let received = std::fs::read(output_file)?;
105    
106    if original == received {
107        println!("   ✅ Files match! Transfer verified.");
108    } else {
109        println!("   ❌ Files don't match! Transfer failed.");
110    }
111    
112    // Cleanup
113    println!();
114    println!("7. Cleanup...");
115    std::fs::remove_file(test_file)?;
116    std::fs::remove_file(output_file)?;
117    println!("   Temporary files removed.");
118    
119    println!();
120    println!("╔════════════════════════════════════════╗");
121    println!("║         Test Complete!                 ║");
122    println!("╚════════════════════════════════════════╝");
123    
124    Ok(())
125}
126
127fn create_test_file(path: &str, size: usize) -> io::Result<()> {
128    let mut file = File::create(path)?;
129    
130    // Create reproducible pattern
131    let mut data = Vec::with_capacity(size);
132    for i in 0..size {
133        data.push((i % 256) as u8);
134    }
135    
136    file.write_all(&data)?;
137    Ok(())
138}