105 lines
3.0 KiB
Rust
105 lines
3.0 KiB
Rust
/* //! Defines the [Step] struct which may be used when initialising the system.
|
|
//!
|
|
//! # Warning
|
|
//!
|
|
//! Use of alloc is currently required, so early initialisation will need a
|
|
//! different method. We should possibly abstract some functionality so that
|
|
//! consumers don't need to worry or care about the difference.
|
|
use alloc::{borrow::ToOwned, boxed::Box, string::String, vec::Vec};
|
|
|
|
use crate::{arch::x86_64::drivers::ascii::WRITER, prelude::*};
|
|
|
|
/// Represents a [Step] when initialising the system.
|
|
///
|
|
/// Handles printing various information to the framebuffer using steps.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rs
|
|
/// // Setup a Step for Foo.
|
|
/// let foo_step: Step<Foo, FooError> = Step::new("foo", Foo::init()).register_tag(|foo| { foo.bar().to_string() });
|
|
/// // This returns a Result<T, E>
|
|
/// let foo = foo_step.run()?;
|
|
/// ```
|
|
///
|
|
/// # TODOs
|
|
///
|
|
/// * If T = Option<T> and None is returned, we print `"[Not found]"`, otherwise
|
|
/// `"[Success]`".
|
|
pub struct Step<T: Clone + ToOwned> {
|
|
/// The initialisation function for the Step, usually this is a closure.
|
|
init_fn: fn() -> T,
|
|
/// A list of tag generator functions to display under the Step on success.
|
|
/// They are displayed like:
|
|
/// ```
|
|
/// Initialising module... [Success]
|
|
/// => Some information here.
|
|
/// ```
|
|
///
|
|
/// # TODOs
|
|
///
|
|
/// * Support tags without alloc being initialised.
|
|
tags: Vec<Box<dyn Fn(T) -> String>>,
|
|
/// The name of the module being initialised.
|
|
task: &'static str,
|
|
}
|
|
|
|
// This impl block might be so horrible it needs its own file.
|
|
impl<T: ToOwned + Clone> Step<T> {
|
|
pub fn new(
|
|
task: &'static str,
|
|
init_fn: fn() -> T,
|
|
tags: Vec<Box<dyn Fn(T) -> String>>,
|
|
) -> Self {
|
|
Self {
|
|
init_fn,
|
|
tags,
|
|
task,
|
|
}
|
|
}
|
|
|
|
/// Runs the initialisation function and logs where required.
|
|
///
|
|
/// This function is a little messy but it just handles pretty printing the
|
|
/// [Step] to the terminal for us.
|
|
pub fn run(self) -> T {
|
|
print_log!(" {}", self.task);
|
|
let mut success_position = WRITER.lock().pos();
|
|
success_position.set_x(success_position.x() + 1);
|
|
|
|
let ret = (self.init_fn)();
|
|
|
|
println!();
|
|
|
|
for tag in &self.tags[..] {
|
|
// Calls the closure on the return value.
|
|
println_log!(" => {}", (tag)(ret.clone()));
|
|
}
|
|
|
|
// Print whether or not the step succeeded.
|
|
print_oneshot!(
|
|
success_position,
|
|
Colour::Green,
|
|
Colour::Black,
|
|
"[Success]"
|
|
);
|
|
|
|
ret
|
|
}
|
|
|
|
/// Registers a 'tag' or note to display under the line which says
|
|
/// `Initialising module... [Success]`.
|
|
///
|
|
/// # Notes
|
|
///
|
|
/// The tag is a closure taking in a reference to T and returning a
|
|
/// presumably formatted String.
|
|
#[allow(unused)]
|
|
pub fn register_tag(&mut self, tag: Box<dyn Fn(T) -> String>) -> &Self {
|
|
self.tags.push(tag);
|
|
|
|
self
|
|
}
|
|
}
|
|
*/
|