use lsp_server::RequestId;
use serde::Serialize;
use tracing::error;
use crate::lsp::result::LSPError;
use crate::server::client::{Notifier, Requester, Responder};
use crate::state::State;
type LocalFn<'s> = Box<dyn FnOnce(&mut State, Notifier, &mut Requester<'_>, Responder) + 's>;
type BackgroundFn = Box<dyn FnOnce(Notifier, Responder) + Send + 'static>;
type BackgroundFnBuilder<'s> = Box<dyn FnOnce(&State) -> BackgroundFn + 's>;
#[derive(Clone, Copy, Debug, Default)]
pub enum BackgroundSchedule {
LatencySensitive,
#[default]
Worker,
}
pub enum Task<'s> {
Background(BackgroundTaskBuilder<'s>),
Sync(SyncTask<'s>),
}
pub struct BackgroundTaskBuilder<'s> {
pub schedule: BackgroundSchedule,
pub builder: BackgroundFnBuilder<'s>,
}
pub struct SyncTask<'s> {
pub func: LocalFn<'s>,
}
impl<'s> Task<'s> {
pub fn background(
schedule: BackgroundSchedule,
func: impl FnOnce(&State) -> Box<dyn FnOnce(Notifier, Responder) + Send + 'static> + 's,
) -> Self {
Self::Background(BackgroundTaskBuilder { schedule, builder: Box::new(func) })
}
pub fn local(
func: impl FnOnce(&mut State, Notifier, &mut Requester<'_>, Responder) + 's,
) -> Self {
Self::Sync(SyncTask { func: Box::new(func) })
}
pub fn immediate<R>(id: RequestId, result: Result<R, LSPError>) -> Self
where
R: Serialize + Send + 'static,
{
Self::local(move |_, _, _, responder| {
if let Err(err) = responder.respond(id, result) {
error!("unable to send immediate response: {err:?}");
}
})
}
pub fn nothing() -> Self {
Self::local(move |_, _, _, _| {})
}
}