use crate::Result;
pub trait ServiceTrait: Send + Sync {
fn name(&self) -> &'static str;
fn version(&self) -> &'static str {
"1.0.0"
}
fn description(&self) -> &'static str {
"OpenLark Service"
}
fn health_check(&self) -> impl std::future::Future<Output = Result<bool>> + Send + '_;
fn start(&self) -> impl std::future::Future<Output = Result<()>> + Send + '_ {
async move {
tracing::info!("服务 '{}' 启动", self.name());
Ok(())
}
}
fn stop(&self) -> impl std::future::Future<Output = Result<()>> + Send + '_ {
async move {
tracing::info!("服务 '{}' 停止", self.name());
Ok(())
}
}
}
pub trait ServiceLifecycle: Send + Sync {
fn start(&self) -> impl std::future::Future<Output = Result<()>> + Send + '_ {
async {
tracing::info!("服务启动");
Ok(())
}
}
fn stop(&self) -> impl std::future::Future<Output = Result<()>> + Send + '_ {
async {
tracing::info!("服务停止");
Ok(())
}
}
fn restart(&self) -> impl std::future::Future<Output = Result<()>> + Send + '_ {
async {
tracing::info!("服务重启");
self.stop().await?;
self.start().await
}
}
fn health_check(&self) -> impl std::future::Future<Output = Result<bool>> + Send + '_ {
std::future::ready(Ok(true))
}
}
#[cfg(test)]
#[allow(unused_imports)]
mod tests {
use super::*;
struct TestService {
name: &'static str,
}
impl ServiceTrait for TestService {
fn name(&self) -> &'static str {
self.name
}
fn health_check(&self) -> impl std::future::Future<Output = Result<bool>> + Send + '_ {
std::future::ready(Ok(true))
}
}
#[tokio::test]
async fn test_service_trait() {
let service = TestService {
name: "test_service",
};
assert_eq!(service.name(), "test_service");
assert_eq!(service.version(), "1.0.0");
assert_eq!(service.description(), "OpenLark Service");
let health = service.health_check().await;
assert!(health.is_ok());
assert!(health.unwrap());
}
}