use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum Hypervisor {
VMware,
VirtualBox,
HyperV,
Qemu,
Unknown,
}
impl Hypervisor {
pub fn from_format(format: &str) -> Self {
match format.to_ascii_lowercase().as_str() {
"vmdk" => Hypervisor::VMware,
"vdi" => Hypervisor::VirtualBox,
"vpc" | "vhd" | "vhdx" => Hypervisor::HyperV,
"qcow" | "qcow2" | "qed" => Hypervisor::Qemu,
_ => Hypervisor::Unknown,
}
}
pub fn name(&self) -> &'static str {
match self {
Hypervisor::VMware => "VMware",
Hypervisor::VirtualBox => "VirtualBox",
Hypervisor::HyperV => "Hyper-V / Virtual PC",
Hypervisor::Qemu => "QEMU / KVM",
Hypervisor::Unknown => "Unknown (raw image or other)",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImageInfo {
pub path: PathBuf,
pub format: String,
pub virtual_size: u64,
pub actual_size: u64,
pub hypervisor: Hypervisor,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Stats {
pub access_mode: String,
pub nbd_requests: u64,
pub bytes_read: u64,
pub duration_ms: u64,
}
pub fn format_bytes(bytes: u64) -> String {
const UNITS: [&str; 5] = ["B", "KiB", "MiB", "GiB", "TiB"];
let mut value = bytes as f64;
let mut idx = 0;
while value >= 1024.0 && idx < UNITS.len() - 1 {
value /= 1024.0;
idx += 1;
}
if idx == 0 {
format!("{} {}", bytes, UNITS[idx])
} else {
format!("{:.1} {}", value, UNITS[idx])
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_format_bytes() {
assert_eq!(format_bytes(500), "500 B");
assert_eq!(format_bytes(1024), "1.0 KiB");
assert_eq!(format_bytes(1024 * 1024), "1.0 MiB");
assert_eq!(format_bytes(1024 * 1024 * 1024 * 2), "2.0 GiB");
}
#[test]
fn test_hypervisor_from_format() {
assert_eq!(Hypervisor::from_format("vmdk"), Hypervisor::VMware);
assert_eq!(Hypervisor::from_format("vdi"), Hypervisor::VirtualBox);
assert_eq!(Hypervisor::from_format("vhdx"), Hypervisor::HyperV);
assert_eq!(Hypervisor::from_format("qcow2"), Hypervisor::Qemu);
assert_eq!(Hypervisor::from_format("raw"), Hypervisor::Unknown);
}
}