pub trait Application {
fn name(&self) -> &str;
fn initialize(&mut self) -> crate::result::hex_result::HexResult<()> {
Result::Ok(())
}
fn run(&mut self) -> crate::result::hex_result::HexResult<()> {
Result::Ok(())
}
fn shutdown(&mut self) -> crate::result::hex_result::HexResult<()> {
Result::Ok(())
}
fn execute(&mut self) -> crate::result::hex_result::HexResult<()> {
self.initialize()?;
let run_result = self.run();
let shutdown_result = self.shutdown();
run_result?;
shutdown_result
}
}
#[cfg(test)]
mod tests {
use super::*;
struct TestApplication {
name: &'static str,
initialized: bool,
ran: bool,
shut_down: bool,
}
impl TestApplication {
fn new(name: &'static str) -> Self {
Self {
name,
initialized: false,
ran: false,
shut_down: false,
}
}
}
impl Application for TestApplication {
fn name(&self) -> &str {
self.name
}
fn initialize(&mut self) -> crate::result::hex_result::HexResult<()> {
self.initialized = true;
Result::Ok(())
}
fn run(&mut self) -> crate::result::hex_result::HexResult<()> {
self.ran = true;
Result::Ok(())
}
fn shutdown(&mut self) -> crate::result::hex_result::HexResult<()> {
self.shut_down = true;
Result::Ok(())
}
}
#[test]
fn test_application_name() {
let app = TestApplication::new("TestApp");
assert_eq!(app.name(), "TestApp");
}
#[test]
fn test_application_lifecycle() {
let mut app = TestApplication::new("TestApp");
assert!(!app.initialized);
assert!(!app.ran);
assert!(!app.shut_down);
let result = app.execute();
assert!(result.is_ok());
assert!(app.initialized);
assert!(app.ran);
assert!(app.shut_down);
}
#[test]
fn test_initialize_only() {
let mut app = TestApplication::new("TestApp");
let result = app.initialize();
assert!(result.is_ok());
assert!(app.initialized);
assert!(!app.ran);
assert!(!app.shut_down);
}
#[test]
fn test_shutdown_only() {
let mut app = TestApplication::new("TestApp");
let result = app.shutdown();
assert!(result.is_ok());
assert!(!app.initialized);
assert!(!app.ran);
assert!(app.shut_down);
}
struct FailingApplication {
fail_at: &'static str,
}
impl Application for FailingApplication {
fn name(&self) -> &str {
"FailingApp"
}
fn initialize(&mut self) -> crate::result::hex_result::HexResult<()> {
if self.fail_at == "initialize" {
return Result::Err(crate::error::hex_error::Hexserror::validation(
"Initialization failed",
));
}
Result::Ok(())
}
fn run(&mut self) -> crate::result::hex_result::HexResult<()> {
if self.fail_at == "run" {
return Result::Err(crate::error::hex_error::Hexserror::validation("Run failed"));
}
Result::Ok(())
}
fn shutdown(&mut self) -> crate::result::hex_result::HexResult<()> {
if self.fail_at == "shutdown" {
return Result::Err(crate::error::hex_error::Hexserror::validation(
"Shutdown failed",
));
}
Result::Ok(())
}
}
#[test]
fn test_execute_fails_on_initialize() {
let mut app = FailingApplication {
fail_at: "initialize",
};
let result = app.execute();
assert!(result.is_err());
}
#[test]
fn test_execute_fails_on_run() {
let mut app = FailingApplication { fail_at: "run" };
let result = app.execute();
assert!(result.is_err());
}
#[test]
fn test_execute_fails_on_shutdown() {
let mut app = FailingApplication {
fail_at: "shutdown",
};
let result = app.execute();
assert!(result.is_err());
}
struct MinimalApplication;
impl Application for MinimalApplication {
fn name(&self) -> &str {
"MinimalApp"
}
}
#[test]
fn test_minimal_application_with_defaults() {
let mut app = MinimalApplication;
assert_eq!(app.name(), "MinimalApp");
let result = app.execute();
assert!(result.is_ok());
}
}