audiobook_forge/models/
result.rs1use serde::{Deserialize, Serialize};
4use std::path::PathBuf;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct ProcessingResult {
9 pub book_name: String,
11 pub success: bool,
13 pub output_path: Option<PathBuf>,
15 pub processing_time: f64,
17 pub error_message: Option<String>,
19 pub output_size: Option<u64>,
21 pub used_copy_mode: bool,
23}
24
25impl ProcessingResult {
26 pub fn new(book_name: String) -> Self {
28 Self {
29 book_name,
30 success: false,
31 output_path: None,
32 processing_time: 0.0,
33 error_message: None,
34 output_size: None,
35 used_copy_mode: false,
36 }
37 }
38
39 pub fn success(mut self, output_path: PathBuf, processing_time: f64, used_copy_mode: bool) -> Self {
41 self.success = true;
42 self.output_path = Some(output_path.clone());
43 self.processing_time = processing_time;
44 self.used_copy_mode = used_copy_mode;
45
46 if let Ok(metadata) = std::fs::metadata(&output_path) {
48 self.output_size = Some(metadata.len());
49 }
50
51 self
52 }
53
54 pub fn failure(mut self, error_message: String, processing_time: f64) -> Self {
56 self.success = false;
57 self.error_message = Some(error_message);
58 self.processing_time = processing_time;
59 self
60 }
61
62 pub fn output_size_mb(&self) -> Option<f64> {
64 self.output_size.map(|size| size as f64 / (1024.0 * 1024.0))
65 }
66}
67
68impl std::fmt::Display for ProcessingResult {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 if self.success {
71 write!(
72 f,
73 "✓ {} ({:.1}s, {})",
74 self.book_name,
75 self.processing_time,
76 if self.used_copy_mode { "copy mode" } else { "transcode" }
77 )?;
78 if let Some(size_mb) = self.output_size_mb() {
79 write!(f, " - {:.1} MB", size_mb)?;
80 }
81 Ok(())
82 } else {
83 write!(
84 f,
85 "✗ {} ({:.1}s) - {}",
86 self.book_name,
87 self.processing_time,
88 self.error_message.as_deref().unwrap_or("Unknown error")
89 )
90 }
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn test_result_success() {
100 let result = ProcessingResult::new("Test Book".to_string())
101 .success(PathBuf::from("/output/test.m4b"), 120.5, true);
102
103 assert!(result.success);
104 assert_eq!(result.processing_time, 120.5);
105 assert!(result.used_copy_mode);
106 assert!(result.output_path.is_some());
107 }
108
109 #[test]
110 fn test_result_failure() {
111 let result = ProcessingResult::new("Test Book".to_string())
112 .failure("FFmpeg failed".to_string(), 45.2);
113
114 assert!(!result.success);
115 assert_eq!(result.processing_time, 45.2);
116 assert_eq!(result.error_message, Some("FFmpeg failed".to_string()));
117 }
118}