use std::fs;
use std::path::{Path, PathBuf};
use serde::Deserialize;
use crate::error::{MbrkitError, Result};
#[derive(Clone, Debug, Deserialize)]
pub struct PackManifest {
pub output: PathBuf,
pub disk_size: String,
pub boot_code: Option<PathBuf>,
pub disk_signature: Option<String>,
pub align_lba: Option<u64>,
pub partition: Vec<PartitionManifest>,
}
#[derive(Clone, Debug, Deserialize)]
pub struct PartitionManifest {
pub file: PathBuf,
#[serde(rename = "type")]
pub partition_type: Option<String>,
pub bootable: Option<bool>,
pub start_lba: Option<u64>,
pub size: Option<String>,
}
impl PackManifest {
pub fn load(path: &Path) -> Result<Self> {
let content = fs::read_to_string(path).map_err(|source| {
MbrkitError::io(
Some(path.to_path_buf()),
"failed to read pack manifest",
source,
)
})?;
toml::from_str(&content).map_err(|source| MbrkitError::Manifest {
path: path.display().to_string(),
source,
})
}
}
#[cfg(test)]
mod tests {
use super::PackManifest;
#[test]
fn manifest_deserializes_partition_entries() {
let manifest = toml::from_str::<PackManifest>(
r#"
output = "disk.img"
disk_size = "32MiB"
boot_code = "mbr.bin"
disk_signature = "0x1234"
align_lba = 2048
[[partition]]
file = "rootfs.img"
type = "minix"
bootable = true
start_lba = 2048
size = "4MiB"
"#,
)
.unwrap();
assert_eq!(manifest.partition.len(), 1);
assert_eq!(manifest.partition[0].file.to_string_lossy(), "rootfs.img");
assert_eq!(
manifest.partition[0].partition_type.as_deref(),
Some("minix")
);
assert_eq!(manifest.partition[0].start_lba, Some(2048));
}
}