First working POC

This commit is contained in:
2026-01-26 22:21:54 +01:00
commit cfddc1edea
255 changed files with 77606 additions and 0 deletions
+135
View File
@@ -0,0 +1,135 @@
//! Download events for progress tracking and status updates
use serde::{Deserialize, Serialize};
/// Events emitted during download operations
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum DownloadEvent {
/// Download has been queued
#[serde(rename_all = "camelCase")]
Queued {
download_id: i64,
item_id: String,
},
/// Download has started
#[serde(rename_all = "camelCase")]
Started {
download_id: i64,
item_id: String,
},
/// Download progress update
#[serde(rename_all = "camelCase")]
Progress {
download_id: i64,
item_id: String,
bytes_downloaded: i64,
total_bytes: Option<i64>,
progress: f64, // 0.0 to 1.0
},
/// Download completed successfully
#[serde(rename_all = "camelCase")]
Completed {
download_id: i64,
item_id: String,
file_path: String,
},
/// Download failed with error
#[serde(rename_all = "camelCase")]
Failed {
download_id: i64,
item_id: String,
error: String,
},
/// Download paused
#[serde(rename_all = "camelCase")]
Paused {
download_id: i64,
item_id: String,
},
/// Download cancelled
#[serde(rename_all = "camelCase")]
Cancelled {
download_id: i64,
item_id: String,
},
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_download_event_serialization_roundtrip() {
let event = DownloadEvent::Progress {
download_id: 1,
item_id: "test123".to_string(),
bytes_downloaded: 1024,
total_bytes: Some(2048),
progress: 0.5,
};
let json = serde_json::to_string(&event).unwrap();
let deserialized: DownloadEvent = serde_json::from_str(&json).unwrap();
match deserialized {
DownloadEvent::Progress {
download_id,
item_id,
progress,
..
} => {
assert_eq!(download_id, 1);
assert_eq!(item_id, "test123");
assert_eq!(progress, 0.5);
}
_ => panic!("Wrong variant"),
}
}
#[test]
fn test_download_event_completed() {
let event = DownloadEvent::Completed {
download_id: 42,
item_id: "song456".to_string(),
file_path: "/path/to/file.mp3".to_string(),
};
let json = serde_json::to_string(&event).unwrap();
assert!(json.contains("\"type\":\"completed\""));
// Verify camelCase field names
assert!(json.contains("\"downloadId\":42"), "Expected downloadId (camelCase), got: {}", json);
assert!(json.contains("\"itemId\":\"song456\""), "Expected itemId (camelCase), got: {}", json);
assert!(json.contains("\"filePath\":"), "Expected filePath (camelCase), got: {}", json);
// Verify roundtrip
let deserialized: DownloadEvent = serde_json::from_str(&json).unwrap();
match deserialized {
DownloadEvent::Completed { file_path, .. } => {
assert_eq!(file_path, "/path/to/file.mp3");
}
_ => panic!("Wrong variant"),
}
}
#[test]
fn test_download_event_failed() {
let event = DownloadEvent::Failed {
download_id: 10,
item_id: "failed_item".to_string(),
error: "Network timeout".to_string(),
};
let json = serde_json::to_string(&event).unwrap();
assert!(json.contains("\"type\":\"failed\""));
// Verify roundtrip
let deserialized: DownloadEvent = serde_json::from_str(&json).unwrap();
match deserialized {
DownloadEvent::Failed { error, .. } => {
assert_eq!(error, "Network timeout");
}
_ => panic!("Wrong variant"),
}
}
}