Skip to main content

cargo_image_runner/runner/
mod.rs

1//! Runner trait and QEMU implementation for executing bootable images.
2
3use crate::core::context::Context;
4use crate::core::error::Result;
5use std::path::Path;
6
7// Runner implementations
8#[cfg(feature = "qemu")]
9pub mod qemu;
10
11/// Runner trait for executing images.
12pub trait Runner: Send + Sync {
13    /// Execute the image.
14    ///
15    /// Returns information about the run result.
16    fn run(&self, ctx: &Context, image_path: &Path) -> Result<RunResult>;
17
18    /// Check if the runner is available on the system.
19    fn is_available(&self) -> bool;
20
21    /// Validate runner configuration.
22    fn validate(&self, ctx: &Context) -> Result<()> {
23        if !self.is_available() {
24            return Err(crate::core::error::Error::runner(format!(
25                "{} is not available on this system",
26                self.name()
27            )));
28        }
29
30        let _ = ctx;
31        Ok(())
32    }
33
34    /// Get a human-readable name for this runner.
35    fn name(&self) -> &str;
36}
37
38/// Result of running an image.
39#[derive(Debug)]
40pub struct RunResult {
41    /// Exit code from the runner.
42    pub exit_code: i32,
43
44    /// Whether the run was considered successful.
45    pub success: bool,
46}
47
48impl RunResult {
49    /// Create a new run result.
50    pub fn new(exit_code: i32, success: bool) -> Self {
51        Self { exit_code, success }
52    }
53
54    /// Create a successful result with exit code 0.
55    pub fn success() -> Self {
56        Self {
57            exit_code: 0,
58            success: true,
59        }
60    }
61
62    /// Create a failed result with the given exit code.
63    pub fn failed(exit_code: i32) -> Self {
64        Self {
65            exit_code,
66            success: false,
67        }
68    }
69}
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74
75    #[test]
76    fn test_run_result_success() {
77        let result = RunResult::success();
78        assert_eq!(result.exit_code, 0);
79        assert!(result.success);
80    }
81
82    #[test]
83    fn test_run_result_failed() {
84        let result = RunResult::failed(1);
85        assert_eq!(result.exit_code, 1);
86        assert!(!result.success);
87    }
88
89    #[test]
90    fn test_run_result_custom() {
91        let result = RunResult::new(33, true);
92        assert_eq!(result.exit_code, 33);
93        assert!(result.success);
94    }
95}