use std::marker::PhantomData;
use std::sync::{Arc, Mutex};
use gen_lsp_types::{ProgressParams, ProgressToken, RequestWithPartialResults};
use crate::client::ClientHandle;
use crate::error::ClientError;
pub(crate) mod sealed {
pub trait Sealed {}
}
pub trait PartialResultRequest:
crate::types::request::Request + RequestWithPartialResults + sealed::Sealed
{
}
#[derive(Clone, Debug)]
pub(crate) struct PartialResultScope {
method: Arc<str>,
token: ProgressToken,
active: Arc<Mutex<bool>>,
}
impl PartialResultScope {
pub(crate) fn new(method: String, token: ProgressToken) -> Self {
Self {
method: method.into(),
token,
active: Arc::new(Mutex::new(true)),
}
}
pub(crate) fn finish(&self) {
*self.active.lock().unwrap() = false;
}
pub(crate) fn method(&self) -> &str {
&self.method
}
}
pub struct PartialResultSink<'a, R: PartialResultRequest> {
client: &'a ClientHandle,
scope: &'a PartialResultScope,
request: PhantomData<R>,
}
impl<'a, R: PartialResultRequest> PartialResultSink<'a, R> {
pub(crate) fn new(client: &'a ClientHandle, scope: &'a PartialResultScope) -> Self {
Self {
client,
scope,
request: PhantomData,
}
}
pub fn report(
&self,
chunk: <R as RequestWithPartialResults>::PartialResult,
) -> Result<(), ClientError> {
let active = self.scope.active.lock().unwrap();
if !*active {
return Err(ClientError::InvalidHelperParams(
"partial-result request has completed".to_string(),
));
}
let value = serde_json::to_value(chunk).map_err(ClientError::Serialize)?;
self.client.progress(ProgressParams {
token: self.scope.token.clone(),
value,
})
}
}
include!(concat!(env!("OUT_DIR"), "/partial_result_requests.rs"));