use std::sync::Arc; use parking_lot::Mutex; use qsu::rt::{InitCtx, RunEnv, ServiceHandler, SvcEvtReader, TermCtx}; #[cfg(feature = "tokio")] use qsu::rt::TokioServiceHandler; #[cfg(feature = "rocket")] use qsu::{ rocket::{Build, Ignite, Rocket}, rt::RocketServiceHandler }; use crate::err::Error; #[derive(Default)] pub struct FailMode { init: bool, run: bool, shutdown: bool } #[allow(unused)] impl FailMode { pub fn init(&mut self) -> &mut Self { self.init = true; self } pub fn run(&mut self) -> &mut Self { self.run = true; self } pub fn shutdown(&mut self) -> &mut Self { self.shutdown = true; self } } #[derive(Default)] pub struct Visited { pub init: bool, pub run: bool, pub shutdown: bool } #[derive(Default)] pub struct MySyncService { pub fail: FailMode, pub visited: Arc> } #[allow(unused)] impl MySyncService { pub fn fail_init(mut self) -> Self { self.fail.init(); self } pub fn fail_run(mut self) -> Self { self.fail.run(); self } pub fn fail_shutdown(mut self) -> Self { self.fail.shutdown(); self } } impl ServiceHandler for MySyncService { fn init(&mut self, _ictx: InitCtx) -> Result<(), qsu::AppErr> { self.visited.lock().init = true; if self.fail.init { Err(Error::hello("From Sync::init()"))?; } Ok(()) } fn run( &mut self, _re: &RunEnv, _set: SvcEvtReader ) -> Result<(), qsu::AppErr> { self.visited.lock().run = true; if self.fail.run { Err(Error::hello("From Sync::run()"))?; } Ok(()) } fn shutdown(&mut self, _tctx: TermCtx) -> Result<(), qsu::AppErr> { self.visited.lock().shutdown = true; if self.fail.shutdown { Err(Error::hello("From Sync::shutdown()"))?; } Ok(()) } } #[cfg(feature = "tokio")] #[derive(Default)] pub struct MyTokioService { pub fail: FailMode, pub visited: Arc> } #[cfg(feature = "tokio")] #[allow(unused)] impl MyTokioService { pub fn fail_init(mut self) -> Self { self.fail.init(); self } pub fn fail_run(mut self) -> Self { self.fail.run(); self } pub fn fail_shutdown(mut self) -> Self { self.fail.shutdown(); self } } #[cfg(feature = "tokio")] #[qsu::async_trait] impl TokioServiceHandler for MyTokioService { async fn init(&mut self, _ictx: InitCtx) -> Result<(), qsu::AppErr> { self.visited.lock().init = true; if self.fail.init { Err(Error::hello("From Tokio::init()"))?; } Ok(()) } async fn run( &mut self, _re: &RunEnv, _set: SvcEvtReader ) -> Result<(), qsu::AppErr> { self.visited.lock().run = true; if self.fail.run { Err(Error::hello("From Tokio::run()"))?; } Ok(()) } async fn shutdown(&mut self, _tctx: TermCtx) -> Result<(), qsu::AppErr> { self.visited.lock().shutdown = true; if self.fail.shutdown { Err(Error::hello("From Tokio::shutdown()"))?; } Ok(()) } } #[cfg(feature = "rocket")] #[derive(Default)] pub struct MyRocketService { pub fail: FailMode, pub visited: Arc> } #[cfg(feature = "rocket")] #[allow(unused)] impl MyRocketService { pub fn fail_init(mut self) -> Self { self.fail.init(); self } pub fn fail_run(mut self) -> Self { self.fail.run(); self } pub fn fail_shutdown(mut self) -> Self { self.fail.shutdown(); self } } #[cfg(feature = "rocket")] #[qsu::async_trait] impl RocketServiceHandler for MyRocketService { async fn init( &mut self, _ictx: InitCtx ) -> Result>, qsu::AppErr> { self.visited.lock().init = true; if self.fail.init { Err(Error::hello("From Rocket::init()"))?; } Ok(Vec::new()) } async fn run( &mut self, _rockets: Vec>, _re: &RunEnv, _set: SvcEvtReader ) -> Result<(), qsu::AppErr> { self.visited.lock().run = true; if self.fail.run { Err(Error::hello("From Rocket::run()"))?; } Ok(()) } async fn shutdown(&mut self, _tctx: TermCtx) -> Result<(), qsu::AppErr> { self.visited.lock().shutdown = true; if self.fail.shutdown { Err(Error::hello("From Rocket::shutdown()"))?; } Ok(()) } } // vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :