use crate::error::ServiceResult;
use std::future::Future;
use std::sync::Arc;
pub trait SunbeamService: Send + Sync + 'static {
fn name(&self) -> &str;
fn version(&self) -> &str {
env!("CARGO_PKG_VERSION")
}
}
pub trait ServiceExt: SunbeamService {
fn shared(self) -> Arc<Self>
where
Self: Sized,
{
Arc::new(self)
}
fn boxed(self) -> Box<dyn SunbeamService>
where
Self: Sized + 'static,
{
Box::new(self)
}
fn on_start(&self) -> impl Future<Output = ServiceResult<()>> + Send {
async { Ok(()) }
}
fn on_stop(&self) -> impl Future<Output = ServiceResult<()>> + Send {
async { Ok(()) }
}
fn health_check(&self) -> impl Future<Output = ServiceResult<()>> + Send {
async { Ok(()) }
}
}
impl<T: SunbeamService> ServiceExt for T {}
#[cfg(test)]
mod tests {
use super::*;
struct TestService;
impl SunbeamService for TestService {
fn name(&self) -> &str {
"test-service"
}
}
#[test]
fn test_service_name() {
let service = TestService;
assert_eq!(service.name(), "test-service");
}
#[test]
fn test_service_version() {
let service = TestService;
assert!(!service.version().is_empty());
}
#[test]
fn test_service_shared() {
let service = TestService;
let shared = service.shared();
assert_eq!(shared.name(), "test-service");
}
#[test]
fn test_service_boxed() {
let service = TestService;
let boxed: Box<dyn SunbeamService> = service.boxed();
assert_eq!(boxed.name(), "test-service");
}
#[tokio::test]
async fn test_service_lifecycle() {
struct LifecycleService;
impl SunbeamService for LifecycleService {
fn name(&self) -> &str {
"lifecycle-service"
}
}
let service = LifecycleService;
service.on_start().await.unwrap();
service.on_stop().await.unwrap();
}
}