rearrange configuration to be closer to where it's consumed

This commit is contained in:
2025-10-11 14:11:31 -07:00
parent 77126e40ae
commit 449eb85ab8
10 changed files with 92 additions and 93 deletions

View File

@@ -1,4 +1,5 @@
use crate::context::Context;
use serde::{Deserialize, Serialize};
use std::rc::Rc;
pub mod chainload;
@@ -7,6 +8,17 @@ pub mod print;
#[cfg(feature = "splash")]
pub mod splash;
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct ActionDeclaration {
#[serde(default)]
pub chainload: Option<chainload::ChainloadConfiguration>,
#[serde(default)]
pub print: Option<print::PrintConfiguration>,
#[serde(default)]
#[cfg(feature = "splash")]
pub splash: Option<splash::SplashConfiguration>,
}
pub fn execute(context: Rc<Context>, name: impl AsRef<str>) {
let Some(action) = context.root().actions().get(name.as_ref()) else {
panic!("unknown action: {}", name.as_ref());

View File

@@ -1,12 +1,19 @@
use crate::config::ChainloadConfiguration;
use crate::context::Context;
use crate::utils;
use log::info;
use serde::{Deserialize, Serialize};
use std::rc::Rc;
use uefi::CString16;
use uefi::proto::device_path::LoadedImageDevicePath;
use uefi::proto::loaded_image::LoadedImage;
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct ChainloadConfiguration {
pub path: String,
#[serde(default)]
pub options: Vec<String>,
}
pub fn chainload(context: Rc<Context>, configuration: &ChainloadConfiguration) {
let sprout_image = uefi::boot::image_handle();
let image_device_path_protocol =

View File

@@ -1,7 +1,13 @@
use crate::config::PrintConfiguration;
use crate::context::Context;
use serde::{Deserialize, Serialize};
use std::rc::Rc;
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct PrintConfiguration {
#[serde(default)]
pub text: String,
}
pub fn print(context: Rc<Context>, configuration: &PrintConfiguration) {
println!("{}", context.stamp(&configuration.text));
}

View File

@@ -1,43 +1,25 @@
use crate::config::SplashConfiguration;
use crate::context::Context;
use crate::utils::framebuffer::Framebuffer;
use crate::utils::read_file_contents;
use image::imageops::{FilterType, resize};
use image::math::Rect;
use image::{DynamicImage, ImageBuffer, ImageFormat, ImageReader, Rgba};
use serde::{Deserialize, Serialize};
use std::io::Cursor;
use std::rc::Rc;
use std::time::Duration;
use uefi::boot::ScopedProtocol;
use uefi::proto::console::gop::{BltOp, BltPixel, BltRegion, GraphicsOutput};
use uefi::proto::console::gop::GraphicsOutput;
struct Framebuffer {
width: usize,
height: usize,
pixels: Vec<BltPixel>,
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct SplashConfiguration {
pub image: String,
#[serde(default = "default_splash_time")]
pub time: u32,
}
impl Framebuffer {
fn new(width: usize, height: usize) -> Self {
Framebuffer {
width,
height,
pixels: vec![BltPixel::new(0, 0, 0); width * height],
}
}
fn pixel(&mut self, x: usize, y: usize) -> Option<&mut BltPixel> {
self.pixels.get_mut(y * self.width + x)
}
fn blit(&self, gop: &mut GraphicsOutput) {
gop.blt(BltOp::BufferToVideo {
buffer: &self.pixels,
src: BltRegion::Full,
dest: (0, 0),
dims: (self.width, self.height),
})
.expect("failed to blit framebuffer");
}
pub fn default_splash_time() -> u32 {
5
}
fn setup_graphics() -> ScopedProtocol<GraphicsOutput> {

View File

@@ -1,3 +1,5 @@
use crate::actions::ActionDeclaration;
use crate::generators::GeneratorDeclaration;
use crate::utils;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
@@ -18,17 +20,6 @@ pub struct RootConfiguration {
pub phases: PhasesConfiguration,
}
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct ActionDeclaration {
#[serde(default)]
pub chainload: Option<ChainloadConfiguration>,
#[serde(default)]
pub print: Option<PrintConfiguration>,
#[serde(default)]
#[cfg(feature = "splash")]
pub splash: Option<SplashConfiguration>,
}
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct EntryDeclaration {
pub title: String,
@@ -38,12 +29,6 @@ pub struct EntryDeclaration {
pub values: BTreeMap<String, String>,
}
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct GeneratorDeclaration {
#[serde(default)]
pub matrix: Option<MatrixConfiguration>,
}
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct PhasesConfiguration {
#[serde(default)]
@@ -58,40 +43,6 @@ pub struct PhaseConfiguration {
pub values: BTreeMap<String, String>,
}
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct MatrixConfiguration {
#[serde(default)]
pub entry: EntryDeclaration,
#[serde(default)]
pub values: BTreeMap<String, Vec<String>>,
}
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct ChainloadConfiguration {
pub path: String,
#[serde(default)]
pub options: Vec<String>,
}
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct PrintConfiguration {
#[serde(default)]
pub text: String,
}
#[cfg(feature = "splash")]
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct SplashConfiguration {
pub image: String,
#[serde(default = "default_splash_time")]
pub time: u32,
}
#[cfg(feature = "splash")]
pub fn default_splash_time() -> u32 {
5
}
pub fn load() -> RootConfiguration {
let content = utils::read_file_contents("sprout.toml");
toml::from_slice(&content).expect("unable to parse sprout.toml file")

View File

@@ -1,11 +1,10 @@
use crate::config::{ActionDeclaration, EntryDeclaration};
use crate::actions::ActionDeclaration;
use std::collections::{BTreeMap, BTreeSet};
use std::rc::Rc;
#[derive(Default)]
pub struct RootContext {
actions: BTreeMap<String, ActionDeclaration>,
entries: BTreeMap<String, (Rc<Context>, EntryDeclaration)>,
}
impl RootContext {
@@ -20,14 +19,6 @@ impl RootContext {
pub fn actions_mut(&mut self) -> &mut BTreeMap<String, ActionDeclaration> {
&mut self.actions
}
pub fn entries(&self) -> &BTreeMap<String, (Rc<Context>, EntryDeclaration)> {
&self.entries
}
pub fn entries_mut(&mut self) -> &mut BTreeMap<String, (Rc<Context>, EntryDeclaration)> {
&mut self.entries
}
}
pub struct Context {

View File

@@ -1,9 +1,17 @@
use crate::config::{EntryDeclaration, GeneratorDeclaration};
use crate::config::EntryDeclaration;
use crate::context::Context;
use crate::generators::matrix::MatrixConfiguration;
use serde::{Deserialize, Serialize};
use std::rc::Rc;
pub mod matrix;
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct GeneratorDeclaration {
#[serde(default)]
pub matrix: Option<MatrixConfiguration>,
}
pub fn generate(
context: Rc<Context>,
generator: &GeneratorDeclaration,

View File

@@ -1,8 +1,17 @@
use crate::config::{EntryDeclaration, MatrixConfiguration};
use crate::config::EntryDeclaration;
use crate::context::Context;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::rc::Rc;
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct MatrixConfiguration {
#[serde(default)]
pub entry: EntryDeclaration,
#[serde(default)]
pub values: BTreeMap<String, Vec<String>>,
}
fn build_matrix(input: &BTreeMap<String, Vec<String>>) -> Vec<BTreeMap<String, String>> {
let items: Vec<(String, Vec<String>)> = input.clone().into_iter().collect();
let mut result: Vec<BTreeMap<String, String>> = vec![BTreeMap::new()];

View File

@@ -4,6 +4,8 @@ use uefi::proto::device_path::text::{AllowShortcuts, DevicePathFromText, Display
use uefi::proto::device_path::{DevicePath, PoolDevicePath};
use uefi::proto::media::fs::SimpleFileSystem;
pub mod framebuffer;
pub fn text_to_device_path(path: &str) -> PoolDevicePath {
let path = CString16::try_from(path).expect("unable to convert path to CString16");
let device_path_from_text = uefi::boot::open_protocol_exclusive::<DevicePathFromText>(

31
src/utils/framebuffer.rs Normal file
View File

@@ -0,0 +1,31 @@
use uefi::proto::console::gop::{BltOp, BltPixel, BltRegion, GraphicsOutput};
pub struct Framebuffer {
width: usize,
height: usize,
pixels: Vec<BltPixel>,
}
impl Framebuffer {
pub fn new(width: usize, height: usize) -> Self {
Framebuffer {
width,
height,
pixels: vec![BltPixel::new(0, 0, 0); width * height],
}
}
pub fn pixel(&mut self, x: usize, y: usize) -> Option<&mut BltPixel> {
self.pixels.get_mut(y * self.width + x)
}
pub fn blit(&self, gop: &mut GraphicsOutput) {
gop.blt(BltOp::BufferToVideo {
buffer: &self.pixels,
src: BltRegion::Full,
dest: (0, 0),
dims: (self.width, self.height),
})
.expect("failed to blit framebuffer");
}
}