Files
sprout/src/main.rs

119 lines
3.5 KiB
Rust
Raw Normal View History

2025-10-01 16:45:04 -07:00
#![feature(uefi_std)]
use crate::config::PhaseConfiguration;
use crate::context::{RootContext, SproutContext};
use anyhow::{Context, Result, bail};
2025-10-05 00:09:53 -07:00
use log::info;
use std::collections::BTreeMap;
use std::ops::Deref;
use std::rc::Rc;
use uefi::proto::device_path::LoadedImageDevicePath;
use uefi::proto::device_path::text::{AllowShortcuts, DisplayOnly};
pub mod actions;
2025-10-01 18:25:49 -07:00
pub mod config;
pub mod context;
2025-10-12 22:39:56 -07:00
pub mod drivers;
pub mod extractors;
pub mod generators;
2025-10-01 16:45:04 -07:00
pub mod setup;
pub mod utils;
2025-10-01 16:45:04 -07:00
fn phase(context: Rc<SproutContext>, phase: &[PhaseConfiguration]) -> Result<()> {
for item in phase {
let mut context = context.fork();
context.insert(&item.values);
let context = context.freeze();
for action in item.actions.iter() {
actions::execute(context.clone(), action)
.context(format!("failed to execute action '{}'", action))?;
}
}
Ok(())
}
fn main() -> Result<()> {
setup::init()?;
2025-10-01 18:25:49 -07:00
let config = config::load()?;
2025-10-05 00:09:53 -07:00
if config.version != config::latest_version() {
bail!("unsupported configuration version: {}", config.version);
2025-10-05 00:09:53 -07:00
}
let mut root = {
let current_image_device_path_protocol = uefi::boot::open_protocol_exclusive::<
LoadedImageDevicePath,
>(uefi::boot::image_handle())
.context("failed to get loaded image device path")?;
let loaded_image_path = current_image_device_path_protocol.deref().to_boxed();
info!(
"loaded image path: {}",
loaded_image_path.to_string(DisplayOnly(false), AllowShortcuts(false))?
);
RootContext::new(loaded_image_path)
};
root.actions_mut().extend(config.actions.clone());
let mut context = SproutContext::new(root);
context.insert(&config.values);
let context = context.freeze();
2025-10-12 22:39:56 -07:00
drivers::load(context.clone(), &config.drivers).context("failed to load drivers")?;
let mut extracted = BTreeMap::new();
for (name, extractor) in &config.extractors {
let value = extractors::extract(context.clone(), extractor)
.context(format!("failed to extract value {}", name))?;
info!("extracted value {}: {}", name, value);
extracted.insert(name.clone(), value);
}
let mut context = context.fork();
context.insert(&extracted);
let context = context.freeze();
phase(context.clone(), &config.phases.startup)?;
let mut all_entries = Vec::new();
for (_name, entry) in config.entries {
all_entries.push((context.clone(), entry));
}
for (_name, generator) in config.generators {
let context = context.fork().freeze();
for entry in generators::generate(context.clone(), &generator)? {
all_entries.push(entry);
}
}
2025-10-04 23:33:23 -07:00
let mut final_entries = Vec::new();
for (context, entry) in all_entries {
let mut context = context.fork();
context.insert(&entry.values);
let context = context.finalize().freeze();
2025-10-04 23:33:23 -07:00
final_entries.push((context, entry));
}
2025-10-05 00:09:53 -07:00
info!("entries:");
2025-10-04 23:33:23 -07:00
for (index, (context, entry)) in final_entries.iter().enumerate() {
let title = context.stamp(&entry.title);
2025-10-05 00:09:53 -07:00
info!(" entry {}: {}", index + 1, title);
2025-10-04 23:33:23 -07:00
}
let index = 1;
let (context, entry) = &final_entries[index - 1];
for action in &entry.actions {
2025-10-05 00:09:53 -07:00
let action = context.stamp(action);
actions::execute(context.clone(), &action)
.context(format!("failed to execute action '{}'", action))?;
}
Ok(())
2025-10-01 16:45:04 -07:00
}