From b941ee51b0881ded9ca6e1f8ab5a8b8b92705f2c Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Sun, 5 Oct 2025 00:09:53 -0700 Subject: [PATCH] add print action --- hack/configs/kernel.sprout.toml | 6 ++++++ src/actions.rs | 9 +++++++-- src/actions/print.rs | 7 +++++++ src/config.rs | 12 ++++++++++-- src/main.rs | 29 +++++++++-------------------- 5 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 src/actions/print.rs diff --git a/hack/configs/kernel.sprout.toml b/hack/configs/kernel.sprout.toml index 33256cd..4f1a2a8 100644 --- a/hack/configs/kernel.sprout.toml +++ b/hack/configs/kernel.sprout.toml @@ -3,6 +3,9 @@ version = 1 [values] default-options = "tty=hvc0" +[actions.welcome] +print.text = "Welcome to Sprout!" + [actions.chainload-kernel] chainload.path = "$path" chainload.options = ["$default-options"] @@ -12,3 +15,6 @@ entry.title = "Boot Kernel $name" entry.values.path = "\\EFI\\BOOT\\$name" entry.actions = ["chainload-kernel"] values.name = ["kernel.efi"] + +[[phases.startup]] +actions = ["welcome"] diff --git a/src/actions.rs b/src/actions.rs index ecefef5..024daff 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -1,14 +1,19 @@ -use crate::config::ActionDeclaration; use crate::context::Context; use std::rc::Rc; pub mod chainload; +pub mod print; -pub fn execute(context: Rc, action: &ActionDeclaration) { +pub fn execute(context: Rc, name: impl AsRef) { + let Some(action) = context.root().actions().get(name.as_ref()) else { + panic!("unknown action: {}", name.as_ref()); + }; let context = context.finalize().freeze(); if let Some(chainload) = &action.chainload { chainload::chainload(context, chainload); + } else if let Some(print) = &action.print { + print::print(context, print); } else { panic!("unknown action configuration"); } diff --git a/src/actions/print.rs b/src/actions/print.rs new file mode 100644 index 0000000..719a1e9 --- /dev/null +++ b/src/actions/print.rs @@ -0,0 +1,7 @@ +use crate::config::PrintConfiguration; +use crate::context::Context; +use std::rc::Rc; + +pub fn print(context: Rc, configuration: &PrintConfiguration) { + println!("{}", context.stamp(&configuration.text)); +} diff --git a/src/config.rs b/src/config.rs index 34264b5..6f15abf 100644 --- a/src/config.rs +++ b/src/config.rs @@ -4,7 +4,7 @@ use std::collections::BTreeMap; #[derive(Serialize, Deserialize, Default, Clone)] pub struct RootConfiguration { - #[serde(default = "default_version")] + #[serde(default = "latest_version")] pub version: u32, #[serde(default)] pub values: BTreeMap, @@ -22,6 +22,8 @@ pub struct RootConfiguration { pub struct ActionDeclaration { #[serde(default)] pub chainload: Option, + #[serde(default)] + pub print: Option, } #[derive(Serialize, Deserialize, Default, Clone)] @@ -68,11 +70,17 @@ pub struct ChainloadConfiguration { pub options: Vec, } +#[derive(Serialize, Deserialize, Default, Clone)] +pub struct PrintConfiguration { + #[serde(default)] + pub text: String, +} + pub fn load() -> RootConfiguration { let content = utils::read_file_contents("sprout.toml"); toml::from_slice(&content).expect("unable to parse sprout.toml file") } -pub fn default_version() -> u32 { +pub fn latest_version() -> u32 { 1 } diff --git a/src/main.rs b/src/main.rs index 77900b0..0e45322 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use crate::config::PhaseConfiguration; use crate::context::{Context, RootContext}; +use log::info; use std::rc::Rc; pub mod actions; @@ -18,10 +19,6 @@ fn phase(context: Rc, phase: &[PhaseConfiguration]) { let context = context.freeze(); for action in item.actions.iter() { - let Some(action) = context.root().actions().get(action) else { - panic!("unknown action: {}", action); - }; - actions::execute(context.clone(), action); } } @@ -31,6 +28,11 @@ fn main() { setup::init(); let config = config::load(); + + if config.version > config::latest_version() { + panic!("unsupported configuration version: {}", config.version); + } + let mut root = RootContext::new(); root.actions_mut().extend(config.actions.clone()); @@ -63,31 +65,18 @@ fn main() { final_entries.push((context, entry)); } - println!("Boot Entries:"); + info!("entries:"); for (index, (context, entry)) in final_entries.iter().enumerate() { let title = context.stamp(&entry.title); - println!(" Entry {}: {}", index + 1, title); + info!(" entry {}: {}", index + 1, title); } - // let mut input = String::new(); - // std::io::stdin().read_line(&mut input).expect("failed to read line"); - // let input = input.trim(); - // let Some(index) = input.parse::().ok().and_then(|value| if value > final_entries.len() { - // None - // } else { - // Some(value) - // }) else { - // eprintln!("invalid entry number"); - // continue; - // }; let index = 1; let (context, entry) = &final_entries[index - 1]; for action in &entry.actions { - let Some(action) = context.root().actions().get(action) else { - panic!("unknown action: {}", action); - }; + let action = context.stamp(action); actions::execute(context.clone(), action); } }