1use std::fmt;
4use std::io;
5use std::path::PathBuf;
6
7#[derive(Debug)]
9pub enum LaunchError {
10 QemuNotFound {
12 searched: Vec<String>,
13 },
14 KvmRequired,
16 NoKernelSegment {
18 path: PathBuf,
19 },
20 KernelExtraction(String),
22 TempFile(io::Error),
24 QemuSpawn(io::Error),
26 QemuExited {
28 code: Option<i32>,
29 stderr: String,
30 },
31 Timeout {
33 seconds: u64,
34 },
35 Qmp(String),
37 QmpIo(io::Error),
39 PortInUse {
41 port: u16,
42 },
43 VmNotRunning,
45 Io(io::Error),
47}
48
49impl fmt::Display for LaunchError {
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 match self {
52 Self::QemuNotFound { searched } => {
53 write!(f, "QEMU not found; searched: {}", searched.join(", "))
54 }
55 Self::KvmRequired => {
56 write!(f, "KVM is required by kernel flags but /dev/kvm is not accessible")
57 }
58 Self::NoKernelSegment { path } => {
59 write!(f, "no KERNEL_SEG found in {}", path.display())
60 }
61 Self::KernelExtraction(msg) => write!(f, "kernel extraction failed: {msg}"),
62 Self::TempFile(e) => write!(f, "failed to create temp file: {e}"),
63 Self::QemuSpawn(e) => write!(f, "failed to spawn QEMU: {e}"),
64 Self::QemuExited { code, stderr } => {
65 write!(f, "QEMU exited with code {code:?}")?;
66 if !stderr.is_empty() {
67 write!(f, ": {stderr}")?;
68 }
69 Ok(())
70 }
71 Self::Timeout { seconds } => {
72 write!(f, "VM did not become ready within {seconds}s")
73 }
74 Self::Qmp(msg) => write!(f, "QMP error: {msg}"),
75 Self::QmpIo(e) => write!(f, "QMP I/O error: {e}"),
76 Self::PortInUse { port } => write!(f, "port {port} is already in use"),
77 Self::VmNotRunning => write!(f, "VM process is not running"),
78 Self::Io(e) => write!(f, "I/O error: {e}"),
79 }
80 }
81}
82
83impl std::error::Error for LaunchError {
84 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
85 match self {
86 Self::TempFile(e) | Self::QemuSpawn(e) | Self::QmpIo(e) | Self::Io(e) => Some(e),
87 _ => None,
88 }
89 }
90}
91
92impl From<io::Error> for LaunchError {
93 fn from(e: io::Error) -> Self {
94 Self::Io(e)
95 }
96}