use crate::app::context::AppContext;
use crate::error::RoadsterResult;
use crate::service::Service;
use async_trait::async_trait;
use axum_core::extract::FromRef;
use std::future::Future;
use std::marker::PhantomData;
use tokio_util::sync::CancellationToken;
#[derive(bon::Builder)]
pub struct FunctionService<S, F, Fut>
where
S: Clone + Send + Sync + 'static,
AppContext: FromRef<S>,
F: Send + Sync + Fn(S, CancellationToken) -> Fut,
Fut: Send + Future<Output = RoadsterResult<()>>,
{
#[builder(into)]
name: String,
enabled: Option<bool>,
function: F,
#[builder(skip)]
_state: PhantomData<S>,
}
#[async_trait]
impl<S, F, Fut> Service<S> for FunctionService<S, F, Fut>
where
S: Clone + Send + Sync + 'static,
AppContext: FromRef<S>,
F: 'static + Send + Sync + Fn(S, CancellationToken) -> Fut,
Fut: 'static + Send + Future<Output = RoadsterResult<()>>,
{
fn name(&self) -> String {
self.name.clone()
}
fn enabled(&self, state: &S) -> bool {
self.enabled
.unwrap_or(AppContext::from_ref(state).config().service.default_enable)
}
async fn run(
self: Box<Self>,
state: &S,
cancel_token: CancellationToken,
) -> RoadsterResult<()> {
(self.function)(state.clone(), cancel_token).await
}
}