use anyhow::{Error, Result}; use std::str::FromStr; #[derive(Default, Debug, Clone)] pub struct BlsEntry { pub title: Option, pub options: Option, pub linux: Option, pub initrd: Option, pub efi: Option, } impl FromStr for BlsEntry { type Err = Error; fn from_str(input: &str) -> Result { let mut title: Option = None; let mut options: Option = None; let mut linux: Option = None; let mut initrd: Option = None; let mut efi: Option = None; for line in input.lines() { let line = line.trim(); let Some((key, value)) = line.split_once(" ") else { continue; }; match key { "title" => { title = Some(value.trim().to_string()); } "options" => { options = Some(value.trim().to_string()); } "linux" => { linux = Some(value.trim().to_string()); } "initrd" => { initrd = Some(value.trim().to_string()); } "efi" => { efi = Some(value.trim().to_string()); } _ => { continue; } } } Ok(BlsEntry { title, options, linux, initrd, efi, }) } } impl BlsEntry { pub fn is_valid(&self) -> bool { self.linux.is_some() || self.efi.is_some() } pub fn chainload_path(&self) -> Option { self.linux .clone() .or(self.efi.clone()) .map(|path| path.replace("/", "\\").trim_start_matches("\\").to_string()) } pub fn initrd_path(&self) -> Option { self.initrd .clone() .map(|path| path.replace("/", "\\").trim_start_matches("\\").to_string()) } pub fn options(&self) -> Option { self.options.clone() } pub fn title(&self) -> Option { self.title.clone() } }