use std::io::Error;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use jsonrpc::RpcError;
pub use jsonrpc::ErrorCode;
pub use transport::Transport;
pub(crate) use jsonrpc::{Callback, EmptyParams, RpcConnection, CancelParams};
pub(crate) use rpc::Endpoint;
use crate::TypeProvider;
use crate::lifecycle::LifecycleService;
use crate::lifecycle::initialize::ClientCapabilities;
use crate::text_document::TextDocumentService;
use crate::window::WindowService;
use crate::workspace::WorkspaceService;
use self::jsonrpc::{RpcConnectionImpl, MessageID};
mod rpc;
mod jsonrpc;
mod transport;
mod lifecycle;
pub struct Server<T: TypeProvider> {
pub connection: Connection<T>,
state: T,
process_id: Option<u32>,
root_uri: Option<String>,
initialization_options: Option<T::InitializeOptions>,
lifecycle: LifecycleService<T>,
pub(crate) window: WindowService<T>,
pub(crate) text_document: TextDocumentService<T>,
pub(crate) workspace: WorkspaceService<T>,
pub(crate) capabilities: ClientCapabilities,
}
pub struct Connection<T: TypeProvider> {
transport: Transport,
error: Option<RpcError>,
current_request: Option<MessageID>,
marker: PhantomData<T>
}
impl<T: TypeProvider> Server<T> {
pub fn new(state: T, transport: Transport) -> Server<T> {
Server {
state,
connection: Connection::new(transport),
process_id: None,
root_uri: None,
initialization_options: None,
lifecycle: Default::default(),
window: Default::default(),
text_document: Default::default(),
workspace: Default::default(),
capabilities: ClientCapabilities::default()
}
}
pub fn process_id(&self) -> Option<u32> {
self.process_id
}
pub fn root_uri(&self) -> Option<&str> {
self.root_uri.as_ref().map(|uri| uri.as_str())
}
pub fn initialization_options(&self) -> Option<&T::InitializeOptions> {
self.initialization_options.as_ref()
}
pub fn split(&mut self) -> (&mut Connection<T>, &mut T) {
(&mut self.connection, &mut self.state)
}
pub fn serve(self) -> Result<(), Error> {
RpcConnectionImpl::serve(self)
}
}
impl<T: TypeProvider> Connection<T> {
fn new(transport: Transport) -> Connection<T> {
Connection {
transport,
error: None,
current_request: None,
marker: PhantomData
}
}
pub fn error<R: Default>(&mut self, code: ErrorCode, message: String) -> R {
self.error = Some(RpcError {
code,
message
});
R::default()
}
pub fn cancelled(&mut self) -> bool {
let Some(id) = self.current_request.clone() else { return false; };
while let Some(params) = self.peek_notification::<CancelParams>("$/cancelRequest") {
if params.id == id {
self.current_request = self.error(
ErrorCode::RequestCancelled,
"Request cancelled".to_string()
);
return true;
}
}
false
}
}
impl<T: TypeProvider> Deref for Server<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.state
}
}
impl<T: TypeProvider> DerefMut for Server<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.state
}
}