mirror of
https://github.com/edera-dev/sprout.git
synced 2026-02-04 07:10:18 +00:00
chore(sprout): implement iterator stamping to cleanup code
This commit is contained in:
@@ -21,7 +21,7 @@ pub fn chainload(context: Rc<SproutContext>, configuration: &ChainloadConfigurat
|
|||||||
// Resolve the path to the image to chainload.
|
// Resolve the path to the image to chainload.
|
||||||
let resolved = eficore::path::resolve_path(
|
let resolved = eficore::path::resolve_path(
|
||||||
Some(context.root().loaded_image_path()?),
|
Some(context.root().loaded_image_path()?),
|
||||||
&context.stamp(&configuration.path),
|
context.stamp(&configuration.path),
|
||||||
)
|
)
|
||||||
.context("unable to resolve chainload path")?;
|
.context("unable to resolve chainload path")?;
|
||||||
|
|
||||||
@@ -38,8 +38,7 @@ pub fn chainload(context: Rc<SproutContext>, configuration: &ChainloadConfigurat
|
|||||||
.context("unable to open loaded image protocol")?;
|
.context("unable to open loaded image protocol")?;
|
||||||
|
|
||||||
// Stamp and combine the options to pass to the image.
|
// Stamp and combine the options to pass to the image.
|
||||||
let options =
|
let options = utils::combine_options(context.stamp_iter(configuration.options.iter()));
|
||||||
utils::combine_options(configuration.options.iter().map(|item| context.stamp(item)));
|
|
||||||
|
|
||||||
// Pass the load options to the image.
|
// Pass the load options to the image.
|
||||||
// If no options are provided, the resulting string will be empty.
|
// If no options are provided, the resulting string will be empty.
|
||||||
@@ -50,6 +49,7 @@ pub fn chainload(context: Rc<SproutContext>, configuration: &ChainloadConfigurat
|
|||||||
.context("unable to convert chainloader options to CString16")?,
|
.context("unable to convert chainloader options to CString16")?,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Ensure the chainloader options limit is not exceeded.
|
||||||
if options.num_bytes() > u32::MAX as usize {
|
if options.num_bytes() > u32::MAX as usize {
|
||||||
bail!("chainloader options too large");
|
bail!("chainloader options too large");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,20 +20,11 @@ use uefi::Guid;
|
|||||||
/// Builds a configuration string for the Xen EFI stub using the specified `configuration`.
|
/// Builds a configuration string for the Xen EFI stub using the specified `configuration`.
|
||||||
fn build_xen_config(context: Rc<SproutContext>, configuration: &EderaConfiguration) -> String {
|
fn build_xen_config(context: Rc<SproutContext>, configuration: &EderaConfiguration) -> String {
|
||||||
// Stamp xen options and combine them.
|
// Stamp xen options and combine them.
|
||||||
let xen_options = utils::combine_options(
|
let xen_options = utils::combine_options(context.stamp_iter(configuration.xen_options.iter()));
|
||||||
configuration
|
|
||||||
.xen_options
|
|
||||||
.iter()
|
|
||||||
.map(|item| context.stamp(item)),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Stamp kernel options and combine them.
|
// Stamp kernel options and combine them.
|
||||||
let kernel_options = utils::combine_options(
|
let kernel_options =
|
||||||
configuration
|
utils::combine_options(context.stamp_iter(configuration.kernel_options.iter()));
|
||||||
.kernel_options
|
|
||||||
.iter()
|
|
||||||
.map(|item| context.stamp(item)),
|
|
||||||
);
|
|
||||||
|
|
||||||
// xen config file format is ini-like
|
// xen config file format is ini-like
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -269,6 +269,15 @@ impl SproutContext {
|
|||||||
Self::stamp_values(&self.all_values(), text.as_ref()).1
|
Self::stamp_values(&self.all_values(), text.as_ref()).1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Stamps all the items from the iterator `input` with all the values in this [SproutContext]
|
||||||
|
/// and it's parents. This calls [self.stamp] on each item.
|
||||||
|
pub fn stamp_iter(
|
||||||
|
&self,
|
||||||
|
input: impl Iterator<Item = impl AsRef<str>>,
|
||||||
|
) -> impl Iterator<Item = String> {
|
||||||
|
input.map(|item| self.stamp(item))
|
||||||
|
}
|
||||||
|
|
||||||
/// Unloads a [SproutContext] back into an owned context. This
|
/// Unloads a [SproutContext] back into an owned context. This
|
||||||
/// may not succeed if something else is holding onto the value.
|
/// may not succeed if something else is holding onto the value.
|
||||||
pub fn unload(self: Rc<SproutContext>) -> Option<SproutContext> {
|
pub fn unload(self: Rc<SproutContext>) -> Option<SproutContext> {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ fn load_driver(context: Rc<SproutContext>, driver: &DriverDeclaration) -> Result
|
|||||||
// Resolve the path to the driver image.
|
// Resolve the path to the driver image.
|
||||||
let resolved = eficore::path::resolve_path(
|
let resolved = eficore::path::resolve_path(
|
||||||
Some(context.root().loaded_image_path()?),
|
Some(context.root().loaded_image_path()?),
|
||||||
&context.stamp(&driver.path),
|
context.stamp(&driver.path),
|
||||||
)
|
)
|
||||||
.context("unable to resolve path to driver")?;
|
.context("unable to resolve path to driver")?;
|
||||||
|
|
||||||
|
|||||||
@@ -22,11 +22,10 @@ pub fn generate(
|
|||||||
|
|
||||||
// Stamp the entry title and actions from the template.
|
// Stamp the entry title and actions from the template.
|
||||||
let mut entry = list.entry.clone();
|
let mut entry = list.entry.clone();
|
||||||
entry.actions = entry
|
|
||||||
.actions
|
// Stamp all the actions this entry references.
|
||||||
.into_iter()
|
entry.actions = context.stamp_iter(entry.actions.into_iter()).collect();
|
||||||
.map(|action| context.stamp(action))
|
|
||||||
.collect();
|
|
||||||
// Push the entry into the list with the new context.
|
// Push the entry into the list with the new context.
|
||||||
entries.push(BootableEntry::new(
|
entries.push(BootableEntry::new(
|
||||||
index.to_string(),
|
index.to_string(),
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ fn cstring16_contains_char(string: &CString16, c: char) -> bool {
|
|||||||
|
|
||||||
/// Parses the input `path` as a [DevicePath].
|
/// Parses the input `path` as a [DevicePath].
|
||||||
/// Uses the [DevicePathFromText] protocol exclusively, and will fail if it cannot acquire the protocol.
|
/// Uses the [DevicePathFromText] protocol exclusively, and will fail if it cannot acquire the protocol.
|
||||||
pub fn text_to_device_path(path: &str) -> Result<PoolDevicePath> {
|
pub fn text_to_device_path(path: impl AsRef<str>) -> Result<PoolDevicePath> {
|
||||||
let path = CString16::try_from(path).context("unable to convert path to CString16")?;
|
let path = CString16::try_from(path.as_ref()).context("unable to convert path to CString16")?;
|
||||||
let device_path_from_text = uefi::boot::open_protocol_exclusive::<DevicePathFromText>(
|
let device_path_from_text = uefi::boot::open_protocol_exclusive::<DevicePathFromText>(
|
||||||
uefi::boot::get_handle_for_protocol::<DevicePathFromText>()
|
uefi::boot::get_handle_for_protocol::<DevicePathFromText>()
|
||||||
.context("no device path from text protocol")?,
|
.context("no device path from text protocol")?,
|
||||||
@@ -113,8 +113,13 @@ pub fn device_path_subpath(path: &DevicePath) -> Result<String> {
|
|||||||
/// Resolve a path specified by `input` to its various components.
|
/// Resolve a path specified by `input` to its various components.
|
||||||
/// Uses `default_root_path` as the base root if one is not specified in the path.
|
/// Uses `default_root_path` as the base root if one is not specified in the path.
|
||||||
/// Returns [ResolvedPath] which contains the resolved components.
|
/// Returns [ResolvedPath] which contains the resolved components.
|
||||||
pub fn resolve_path(default_root_path: Option<&DevicePath>, input: &str) -> Result<ResolvedPath> {
|
pub fn resolve_path(
|
||||||
let mut path = text_to_device_path(input).context("unable to convert text to path")?;
|
default_root_path: Option<&DevicePath>,
|
||||||
|
input: impl ToString,
|
||||||
|
) -> Result<ResolvedPath> {
|
||||||
|
let mut input = input.to_string();
|
||||||
|
|
||||||
|
let mut path = text_to_device_path(&input).context("unable to convert text to path")?;
|
||||||
let path_has_device = path
|
let path_has_device = path
|
||||||
.node_iter()
|
.node_iter()
|
||||||
.next()
|
.next()
|
||||||
@@ -125,7 +130,6 @@ pub fn resolve_path(default_root_path: Option<&DevicePath>, input: &str) -> Resu
|
|||||||
.map(|it| it.to_string().contains('('))
|
.map(|it| it.to_string().contains('('))
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if !path_has_device {
|
if !path_has_device {
|
||||||
let mut input = input.to_string();
|
|
||||||
if !input.starts_with('\\') {
|
if !input.starts_with('\\') {
|
||||||
input.insert(0, '\\');
|
input.insert(0, '\\');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ impl<'a> ShimInput<'a> {
|
|||||||
let path = path
|
let path = path
|
||||||
.to_string(DisplayOnly(false), AllowShortcuts(false))
|
.to_string(DisplayOnly(false), AllowShortcuts(false))
|
||||||
.context("unable to convert device path to string")?;
|
.context("unable to convert device path to string")?;
|
||||||
let path = crate::path::resolve_path(None, &path.to_string())
|
let path = crate::path::resolve_path(None, path.to_string())
|
||||||
.context("unable to resolve path")?;
|
.context("unable to resolve path")?;
|
||||||
// Read the file path.
|
// Read the file path.
|
||||||
let data = path.read_file()?;
|
let data = path.read_file()?;
|
||||||
|
|||||||
Reference in New Issue
Block a user