use alloc::string::String;
use alloc::vec::Vec;
use super::super::boot::options::BootOptions;
use super::super::read::PathSeparator;
use super::super::rrip::RripOptions;
use crate::file::EntryType;
use crate::joliet::JolietLevel;
#[derive(Debug, Clone, Default)]
pub struct HybridBootOptions {
pub partition_scheme: PartitionScheme,
pub mbr_bootstrap: Option<alloc::vec::Vec<u8>>,
pub bootable: bool,
pub efi_boot_partition: Option<String>,
}
impl HybridBootOptions {
pub fn mbr() -> Self {
Self {
partition_scheme: PartitionScheme::Mbr,
mbr_bootstrap: None,
bootable: true,
efi_boot_partition: None,
}
}
pub fn gpt() -> Self {
Self {
partition_scheme: PartitionScheme::Gpt,
mbr_bootstrap: None,
bootable: false,
efi_boot_partition: None,
}
}
pub fn hybrid() -> Self {
Self {
partition_scheme: PartitionScheme::Hybrid,
mbr_bootstrap: None,
bootable: true,
efi_boot_partition: None,
}
}
pub fn bootstrap(mut self, bootstrap: alloc::vec::Vec<u8>) -> Self {
self.mbr_bootstrap = Some(bootstrap);
self
}
pub fn with_efi_boot_partition(mut self, path: impl Into<String>) -> Self {
self.efi_boot_partition = Some(path.into());
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum PartitionScheme {
#[default]
None,
Mbr,
Gpt,
Hybrid,
}
#[derive(Debug, Clone)]
pub struct IsoFormatOptions {
pub volume_name: String,
pub system_id: Option<String>,
pub volume_set_id: Option<String>,
pub publisher_id: Option<String>,
pub preparer_id: Option<String>,
pub application_id: Option<String>,
pub sector_size: usize,
pub features: CreationFeatures,
pub path_separator: PathSeparator,
pub strict_charset: bool,
}
impl IsoFormatOptions {
pub(crate) fn partition_scheme(&self) -> Option<PartitionScheme> {
self.features
.hybrid_boot
.as_ref()
.map(|h| h.partition_scheme)
}
pub(crate) fn has_rock_ridge_deep_dirs(&self) -> bool {
self.features
.rock_ridge
.is_some_and(|options| options.enabled && options.relocate_deep_dirs)
}
pub(crate) fn entry_types(&self) -> Vec<EntryType> {
let mut entry_types = Vec::new();
entry_types.push(self.features.filenames.into());
if self.features.long_filenames {
entry_types.push(EntryType::Level3 {
supports_lowercase: true,
supports_rrip: false,
});
}
if let Some(joliet) = self.features.joliet {
entry_types.push(joliet.into());
}
entry_types
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BaseIsoLevel {
Level1 {
supports_lowercase: bool,
supports_rrip: bool,
},
Level2 {
supports_lowercase: bool,
supports_rrip: bool,
},
Level3 {
supports_lowercase: bool,
supports_rrip: bool,
},
}
#[derive(Debug, Clone)]
pub struct CreationFeatures {
pub filenames: BaseIsoLevel,
pub long_filenames: bool,
pub joliet: Option<JolietLevel>,
pub rock_ridge: Option<RripOptions>,
pub el_torito: Option<BootOptions>,
pub hybrid_boot: Option<HybridBootOptions>,
}
impl Default for CreationFeatures {
fn default() -> Self {
Self {
filenames: BaseIsoLevel::Level1 {
supports_lowercase: false,
supports_rrip: false,
},
long_filenames: false,
joliet: None,
rock_ridge: None,
el_torito: None,
hybrid_boot: None,
}
}
}
impl CreationFeatures {
pub fn rock_ridge() -> Self {
Self {
filenames: BaseIsoLevel::Level1 {
supports_lowercase: false,
supports_rrip: true,
},
rock_ridge: Some(RripOptions::default()),
..Default::default()
}
}
pub fn joliet(level: JolietLevel) -> Self {
Self {
joliet: Some(level),
..Default::default()
}
}
pub fn extensions() -> Self {
Self {
filenames: BaseIsoLevel::Level1 {
supports_lowercase: false,
supports_rrip: true,
},
joliet: Some(JolietLevel::Level3),
rock_ridge: Some(RripOptions::default()),
..Default::default()
}
}
pub fn hybrid_boot(scheme: PartitionScheme) -> Self {
Self {
hybrid_boot: Some(HybridBootOptions {
partition_scheme: scheme,
mbr_bootstrap: None,
bootable: true,
efi_boot_partition: None,
}),
..Default::default()
}
}
}
impl From<BaseIsoLevel> for crate::file::EntryType {
fn from(value: BaseIsoLevel) -> Self {
match value {
BaseIsoLevel::Level1 {
supports_lowercase,
supports_rrip,
} => Self::Level1 {
supports_lowercase,
supports_rrip,
},
BaseIsoLevel::Level2 {
supports_lowercase,
supports_rrip,
} => Self::Level2 {
supports_lowercase,
supports_rrip,
},
BaseIsoLevel::Level3 {
supports_lowercase,
supports_rrip,
} => Self::Level2 {
supports_lowercase,
supports_rrip,
},
}
}
}