use crate::diskimage::DiskImageFlags;
use crate::{DiskCh, DiskDataResolution, DiskImage, DiskImageError, StandardFormat};
#[derive(Default)]
pub struct ImageBuilder {
#[doc = "Specify the [`StandardFormat`] to use for the [`DiskImage`] to be built."]
pub standard_format: Option<StandardFormat>,
#[doc = "Specify the [`DiskDataResolution`] to use for the DiskImage to be built."]
pub resolution: Option<DiskDataResolution>,
#[doc = "Specify the creator tag to display during boot."]
pub creator_tag: Option<[u8; 8]>,
#[doc = "Specify whether the DiskImage should be formatted."]
pub formatted: bool,
}
impl ImageBuilder {
pub fn new() -> ImageBuilder {
Default::default()
}
pub fn with_standard_format(mut self, standard_format: StandardFormat) -> ImageBuilder {
self.standard_format = Some(standard_format);
self
}
pub fn with_resolution(mut self, resolution: DiskDataResolution) -> ImageBuilder {
self.resolution = Some(resolution);
self
}
pub fn with_formatted(mut self, formatted: bool) -> ImageBuilder {
self.formatted = formatted;
self
}
pub fn with_creator_tag(mut self, creator_tag: &[u8]) -> ImageBuilder {
let mut new_creator_tag = [0x20; 8];
let max_len = creator_tag.len().min(8);
new_creator_tag[..max_len].copy_from_slice(&creator_tag[..max_len]);
self.creator_tag = Some(new_creator_tag);
self
}
pub fn build(self) -> Result<DiskImage, DiskImageError> {
if self.resolution.is_none() {
log::error!("DiskDataResolution not set");
return Err(DiskImageError::ParameterError);
}
if self.standard_format.is_some() {
match self.resolution {
Some(DiskDataResolution::BitStream) => self.build_bitstream(),
None | Some(DiskDataResolution::MetaSector) => self.build_bytestream(),
_ => Err(DiskImageError::UnsupportedFormat),
}
} else {
Err(DiskImageError::UnsupportedFormat)
}
}
fn build_bitstream(self) -> Result<DiskImage, DiskImageError> {
let format = self.standard_format.unwrap();
let mut disk_image = DiskImage::create(format);
disk_image.set_resolution(DiskDataResolution::BitStream);
let chsn = format.get_chsn();
let encoding = format.get_encoding();
let data_rate = format.get_data_rate();
let bitcell_size = format.get_bitcell_ct();
for head in 0..chsn.h() {
for cylinder in 0..chsn.c() {
let ch = DiskCh::new(cylinder, head);
disk_image.add_empty_track(ch, encoding, data_rate, bitcell_size)?;
}
}
if self.formatted {
disk_image.format(format, None, self.creator_tag.as_ref())?;
}
disk_image.post_load_process();
disk_image.clear_flag(DiskImageFlags::DIRTY);
Ok(disk_image)
}
fn build_bytestream(self) -> Result<DiskImage, DiskImageError> {
let mut disk_image = DiskImage::create(self.standard_format.unwrap());
disk_image.set_resolution(DiskDataResolution::MetaSector);
disk_image.post_load_process();
disk_image.clear_flag(DiskImageFlags::DIRTY);
Ok(disk_image)
}
}