This commit is contained in:
Aleksey Kladov 2018-08-10 23:56:19 +03:00
parent bf42a75f1e
commit 52de08330f
3 changed files with 29 additions and 27 deletions

View file

@ -9,20 +9,17 @@ use drop_bomb::DropBomb;
use ::{ use ::{
Result, Result,
req::{Request, Notification}, req::{ClientRequest, Notification},
io::{Io, RawMsg, RawResponse, RawRequest, RawNotification}, io::{Io, RawMsg, RawResponse, RawRequest, RawNotification},
}; };
pub struct Responder<R: Request> { pub struct Responder<R: ClientRequest> {
id: u64, id: u64,
bomb: DropBomb, bomb: DropBomb,
ph: PhantomData<R>, ph: PhantomData<R>,
} }
impl<R: Request> Responder<R> impl<R: ClientRequest> Responder<R>
where
R::Params: DeserializeOwned,
R::Result: Serialize,
{ {
pub fn response(self, io: &mut Io, resp: Result<R::Result>) -> Result<()> { pub fn response(self, io: &mut Io, resp: Result<R::Result>) -> Result<()> {
match resp { match resp {
@ -52,11 +49,8 @@ impl<R: Request> Responder<R>
} }
fn parse_request_as<R>(raw: RawRequest) -> Result<::std::result::Result<(R::Params, Responder<R>), RawRequest>> fn parse_request_as<R: ClientRequest>(raw: RawRequest)
where -> Result<::std::result::Result<(R::Params, Responder<R>), RawRequest>>
R: Request,
R::Params: DeserializeOwned,
R::Result: Serialize,
{ {
if raw.method != R::METHOD { if raw.method != R::METHOD {
return Ok(Err(raw)); return Ok(Err(raw));
@ -73,9 +67,7 @@ fn parse_request_as<R>(raw: RawRequest) -> Result<::std::result::Result<(R::Para
pub fn handle_request<R, F>(req: &mut Option<RawRequest>, f: F) -> Result<()> pub fn handle_request<R, F>(req: &mut Option<RawRequest>, f: F) -> Result<()>
where where
R: Request, R: ClientRequest,
R::Params: DeserializeOwned,
R::Result: Serialize,
F: FnOnce(R::Params, Responder<R>) -> Result<()> F: FnOnce(R::Params, Responder<R>) -> Result<()>
{ {
match req.take() { match req.take() {
@ -90,11 +82,8 @@ pub fn handle_request<R, F>(req: &mut Option<RawRequest>, f: F) -> Result<()>
} }
} }
pub fn expect_request<R>(io: &mut Io, raw: RawRequest) -> Result<Option<(R::Params, Responder<R>)>> pub fn expect_request<R: ClientRequest>(io: &mut Io, raw: RawRequest)
where -> Result<Option<(R::Params, Responder<R>)>>
R: Request,
R::Params: DeserializeOwned,
R::Result: Serialize,
{ {
let ret = match parse_request_as::<R>(raw)? { let ret = match parse_request_as::<R>(raw)? {
Ok(x) => Some(x), Ok(x) => Some(x),

View file

@ -28,12 +28,10 @@ use threadpool::ThreadPool;
use crossbeam_channel::{bounded, Sender, Receiver}; use crossbeam_channel::{bounded, Sender, Receiver};
use flexi_logger::Logger; use flexi_logger::Logger;
use languageserver_types::{TextDocumentItem, VersionedTextDocumentIdentifier, TextDocumentIdentifier}; use languageserver_types::{TextDocumentItem, VersionedTextDocumentIdentifier, TextDocumentIdentifier};
use serde::{ser::Serialize, de::DeserializeOwned};
use libanalysis::{WorldState, World}; use libanalysis::{WorldState, World};
use ::{ use ::{
io::{Io, RawMsg, RawRequest}, io::{Io, RawMsg, RawRequest},
req::Request,
handlers::{handle_syntax_tree, handle_extend_selection, publish_diagnostics}, handlers::{handle_syntax_tree, handle_extend_selection, publish_diagnostics},
}; };
@ -261,17 +259,13 @@ fn main_loop(
} }
} }
fn handle_request_on_threadpool<R>( fn handle_request_on_threadpool<R: req::ClientRequest>(
req: &mut Option<RawRequest>, req: &mut Option<RawRequest>,
pool: &ThreadPool, pool: &ThreadPool,
world: &WorldState, world: &WorldState,
sender: &Sender<Thunk>, sender: &Sender<Thunk>,
f: fn(World, R::Params) -> Result<R::Result>, f: fn(World, R::Params) -> Result<R::Result>,
) -> Result<()> ) -> Result<()>
where
R: Request + Send + 'static,
R::Params: DeserializeOwned + Send + 'static,
R::Result: Serialize + Send + 'static,
{ {
dispatch::handle_request::<R, _>(req, |params, resp| { dispatch::handle_request::<R, _>(req, |params, resp| {
let world = world.snapshot(); let world = world.snapshot();

View file

@ -1,10 +1,29 @@
use serde::{ser::Serialize, de::DeserializeOwned};
use languageserver_types::{TextDocumentIdentifier, Range}; use languageserver_types::{TextDocumentIdentifier, Range};
pub use languageserver_types::{ pub use languageserver_types::{
request::*, notification::*, request::*, notification::*,
InitializeResult, PublishDiagnosticsParams InitializeResult, PublishDiagnosticsParams,
}; };
pub trait ClientRequest: Send + 'static {
type Params: DeserializeOwned + Send + 'static;
type Result: Serialize + Send + 'static;
const METHOD: &'static str;
}
impl<T> ClientRequest for T
where T: Request + Send + 'static,
T::Params: DeserializeOwned + Send + 'static,
T::Result: Serialize + Send + 'static,
{
type Params = <T as Request>::Params;
type Result = <T as Request>::Result;
const METHOD: &'static str = <T as Request>::METHOD;
}
pub enum SyntaxTree {} pub enum SyntaxTree {}
impl Request for SyntaxTree { impl Request for SyntaxTree {