1#[cfg(feature = "dap")]
4mod dap_srv;
5
6#[cfg(feature = "lsp")]
7mod lsp_srv;
8
9use core::fmt;
10use std::any::Any;
11use std::collections::HashMap;
12use std::path::{Path, PathBuf};
13use std::pin::Pin;
14use std::sync::atomic::AtomicI32;
15#[cfg(feature = "web")]
16use std::sync::atomic::AtomicU32;
17use std::sync::{Arc, Weak};
18
19use futures::future::MaybeDone;
20use parking_lot::Mutex;
21use serde::Serialize;
22use serde_json::{Value as JsonValue, from_value};
23use tinymist_std::time::Time;
24
25use crate::msg::*;
26use crate::req_queue;
27use crate::*;
28
29type ImmutPath = Arc<Path>;
30
31pub type ResponseFuture<T> = MaybeDone<Pin<Box<dyn std::future::Future<Output = T> + Send>>>;
33pub type LspResponseFuture<T> = LspResult<ResponseFuture<T>>;
35pub type SchedulableResponse<T> = LspResponseFuture<LspResult<T>>;
37pub type AnySchedulableResponse = SchedulableResponse<JsonValue>;
39pub type ScheduleResult = AnySchedulableResponse;
41pub type ScheduledResult = LspResult<Option<()>>;
47
48pub type ConnectionTx = TConnectionTx<Message>;
50pub type ConnectionRx = TConnectionRx<Message>;
52
53#[derive(Debug, Clone)]
55pub struct TConnectionTx<M> {
56 pub event: crossbeam_channel::Sender<Event>,
58 pub lsp: crossbeam_channel::Sender<Message>,
60 pub(crate) marker: std::marker::PhantomData<M>,
61}
62
63#[derive(Debug, Clone)]
65pub struct TConnectionRx<M> {
66 pub event: crossbeam_channel::Receiver<Event>,
68 pub lsp: crossbeam_channel::Receiver<Message>,
70 pub(crate) marker: std::marker::PhantomData<M>,
71}
72
73impl<M: TryFrom<Message, Error = anyhow::Error>> TConnectionRx<M> {
74 pub fn recv(&self) -> anyhow::Result<EventOrMessage<M>> {
76 crossbeam_channel::select_biased! {
77 recv(self.lsp) -> msg => Ok(EventOrMessage::Msg(msg?.try_into()?)),
78 recv(self.event) -> event => Ok(event.map(EventOrMessage::Evt)?),
79 }
80 }
81}
82
83pub enum EventOrMessage<M> {
85 Evt(Event),
87 Msg(M),
89}
90
91pub struct Connection<M> {
93 pub sender: TConnectionTx<M>,
95 pub receiver: TConnectionRx<M>,
97}
98
99impl<M: TryFrom<Message, Error = anyhow::Error>> From<Connection<Message>> for Connection<M> {
100 fn from(conn: Connection<Message>) -> Self {
101 Self {
102 sender: TConnectionTx {
103 event: conn.sender.event,
104 lsp: conn.sender.lsp,
105 marker: std::marker::PhantomData,
106 },
107 receiver: TConnectionRx {
108 event: conn.receiver.event,
109 lsp: conn.receiver.lsp,
110 marker: std::marker::PhantomData,
111 },
112 }
113 }
114}
115
116impl<M: TryFrom<Message, Error = anyhow::Error>> From<TConnectionTx<M>> for ConnectionTx {
117 fn from(conn: TConnectionTx<M>) -> Self {
118 Self {
119 event: conn.event,
120 lsp: conn.lsp,
121 marker: std::marker::PhantomData,
122 }
123 }
124}
125
126type AnyCaster<S> = Arc<dyn Fn(&mut dyn Any) -> &mut S + Send + Sync>;
127
128pub struct TypedLspClient<S> {
130 client: LspClient,
131 caster: AnyCaster<S>,
132}
133
134impl<S> TypedLspClient<S> {
135 pub fn to_untyped(self) -> LspClient {
137 self.client
138 }
139}
140
141impl<S: 'static> TypedLspClient<S> {
142 pub fn untyped(&self) -> &LspClient {
144 &self.client
145 }
146
147 pub fn cast<T: 'static>(&self, f: fn(&mut S) -> &mut T) -> TypedLspClient<T> {
149 let caster = self.caster.clone();
150 TypedLspClient {
151 client: self.client.clone(),
152 caster: Arc::new(move |s| f(caster(s))),
153 }
154 }
155
156 pub fn send_event<T: std::any::Any + Send + 'static>(&self, event: T) {
158 self.sender.send_event(event);
159 }
160}
161
162impl<S> Clone for TypedLspClient<S> {
163 fn clone(&self) -> Self {
164 Self {
165 client: self.client.clone(),
166 caster: self.caster.clone(),
167 }
168 }
169}
170
171impl<S> std::ops::Deref for TypedLspClient<S> {
172 type Target = LspClient;
173
174 fn deref(&self) -> &Self::Target {
175 &self.client
176 }
177}
178
179#[derive(Debug, Clone)]
184pub struct LspClientRoot {
185 weak: LspClient,
186 _strong: Arc<ConnectionTx>,
187}
188
189impl LspClientRoot {
190 pub fn new<M: TryFrom<Message, Error = anyhow::Error> + GetMessageKind>(
192 handle: tokio::runtime::Handle,
193 sender: TConnectionTx<M>,
194 ) -> Self {
195 let _strong = Arc::new(sender.into());
196 let weak = LspClient {
197 handle,
198 msg_kind: M::MESSAGE_KIND,
199 sender: TransportHost::System(SystemTransportSender {
200 sender: Arc::downgrade(&_strong),
201 }),
202 req_queue: Arc::new(Mutex::new(ReqQueue::default())),
203
204 hook: Arc::new(()),
205 };
206 Self { weak, _strong }
207 }
208
209 #[cfg(feature = "web")]
211 pub fn new_js(handle: tokio::runtime::Handle, sender: JsTransportSender) -> Self {
212 let dummy = dummy_transport::<LspMessage>();
213
214 let _strong = Arc::new(dummy.sender.into());
215 let weak = LspClient {
216 handle,
217 msg_kind: LspMessage::MESSAGE_KIND,
218 sender: TransportHost::Js {
219 event_id: Arc::new(AtomicU32::new(0)),
220 events: Arc::new(Mutex::new(HashMap::new())),
221 sender,
222 },
223 req_queue: Arc::new(Mutex::new(ReqQueue::default())),
224
225 hook: Arc::new(()),
226 };
227 Self { weak, _strong }
228 }
229
230 pub fn with_hook(mut self, hook: Arc<dyn LsHook>) -> Self {
232 self.weak.hook = hook;
233 self
234 }
235
236 pub fn weak(&self) -> LspClient {
238 self.weak.clone()
239 }
240}
241
242type ReqHandler = Box<dyn for<'a> FnOnce(&'a mut dyn Any, LspOrDapResponse) + Send + Sync>;
243type ReqQueue = req_queue::ReqQueue<(String, Time), ReqHandler>;
244
245#[derive(Debug, Clone)]
247pub enum TransportHost {
248 System(SystemTransportSender),
250 #[cfg(feature = "web")]
252 Js {
253 event_id: Arc<AtomicU32>,
255 events: Arc<Mutex<HashMap<u32, Event>>>,
257 sender: JsTransportSender,
259 },
260}
261
262#[derive(Debug, Clone)]
264pub struct SystemTransportSender {
265 pub(crate) sender: Weak<ConnectionTx>,
267}
268
269#[cfg(feature = "web")]
271#[derive(Debug, Clone, serde::Deserialize)]
272#[serde(rename_all = "camelCase")]
273pub struct JsTransportSender {
274 #[serde(with = "serde_wasm_bindgen::preserve")]
275 pub(crate) send_event: js_sys::Function,
276 #[serde(with = "serde_wasm_bindgen::preserve")]
277 pub(crate) send_request: js_sys::Function,
278 #[serde(with = "serde_wasm_bindgen::preserve")]
279 pub(crate) send_notification: js_sys::Function,
280 #[serde(with = "serde_wasm_bindgen::preserve")]
282 pub resolve_fn: js_sys::Function,
283}
284
285#[cfg(feature = "web")]
286unsafe impl Send for TransportHost {}
289
290#[cfg(feature = "web")]
291unsafe impl Sync for TransportHost {}
294
295impl TransportHost {
296 pub fn send_event<T: std::any::Any + Send + 'static>(&self, event: T) {
298 match self {
299 TransportHost::System(host) => {
300 let Some(sender) = host.sender.upgrade() else {
301 log::warn!("failed to send request: connection closed");
302 return;
303 };
304
305 if let Err(res) = sender.event.send(Box::new(event)) {
306 log::warn!("failed to send event: {res:?}");
307 }
308 }
309 #[cfg(feature = "web")]
310 TransportHost::Js {
311 event_id,
312 sender,
313 events,
314 } => {
315 let event_id = {
316 let event_id = event_id.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
317 let mut lg = events.lock();
318 lg.insert(event_id, Box::new(event));
319 js_sys::Number::from(event_id)
320 };
321 if let Err(err) = sender
322 .send_event
323 .call1(&wasm_bindgen::JsValue::UNDEFINED, &event_id.into())
324 {
325 log::error!("failed to send event: {err:?}");
326 }
327 }
328 }
329 }
330
331 pub fn send_message(&self, response: Message) {
333 match self {
334 TransportHost::System(host) => {
335 let Some(sender) = host.sender.upgrade() else {
336 log::warn!("failed to send response: connection closed");
337 return;
338 };
339 if let Err(res) = sender.lsp.send(response) {
340 log::warn!("failed to send response: {res:?}");
341 }
342 }
343 #[cfg(feature = "web")]
344 TransportHost::Js { sender, .. } => match response {
345 #[cfg(feature = "lsp")]
346 Message::Lsp(lsp::Message::Request(req)) => {
347 let msg = to_js_value(&req).expect("failed to serialize request to js value");
348 if let Err(err) = sender
349 .send_request
350 .call1(&wasm_bindgen::JsValue::UNDEFINED, &msg)
351 {
352 log::error!("failed to send request: {err:?}");
353 }
354 }
355 #[cfg(feature = "lsp")]
356 Message::Lsp(lsp::Message::Notification(req)) => {
357 let msg = to_js_value(&req).expect("failed to serialize request to js value");
358 if let Err(err) = sender
359 .send_notification
360 .call1(&wasm_bindgen::JsValue::UNDEFINED, &msg)
361 {
362 log::error!("failed to send request: {err:?}");
363 }
364 }
365 #[cfg(feature = "lsp")]
366 Message::Lsp(lsp::Message::Response(req)) => {
367 panic!("unexpected response to js world: {req:?}");
368 }
369 #[cfg(feature = "dap")]
370 Message::Dap(dap::Message::Request(req)) => {
371 let msg = to_js_value(&req).expect("failed to serialize request to js value");
372 if let Err(err) = sender
373 .send_request
374 .call1(&wasm_bindgen::JsValue::UNDEFINED, &msg)
375 {
376 log::error!("failed to send request: {err:?}");
377 }
378 }
379 #[cfg(feature = "dap")]
380 Message::Dap(dap::Message::Event(req)) => {
381 let msg = to_js_value(&req).expect("failed to serialize request to js value");
382 if let Err(err) = sender
383 .send_notification
384 .call1(&wasm_bindgen::JsValue::UNDEFINED, &msg)
385 {
386 log::error!("failed to send request: {err:?}");
387 }
388 }
389 #[cfg(feature = "dap")]
390 Message::Dap(dap::Message::Response(req)) => {
391 panic!("unexpected response to js world: {req:?}");
392 }
393 },
394 }
395 }
396}
397
398#[cfg(feature = "web")]
401fn to_js_value<T: serde::Serialize>(
402 value: &T,
403) -> Result<wasm_bindgen::JsValue, serde_wasm_bindgen::Error> {
404 value.serialize(&serde_wasm_bindgen::Serializer::new().serialize_maps_as_objects(true))
405}
406
407#[derive(Debug, Clone)]
409pub struct LspClient {
410 pub handle: tokio::runtime::Handle,
412
413 pub(crate) msg_kind: MessageKind,
414 pub sender: TransportHost,
416 pub(crate) req_queue: Arc<Mutex<ReqQueue>>,
417
418 pub(crate) hook: Arc<dyn LsHook>,
419}
420
421impl LspClient {
422 pub fn untyped(&self) -> &Self {
424 self
425 }
426
427 pub fn to_typed<S: Any>(&self) -> TypedLspClient<S> {
429 TypedLspClient {
430 client: self.clone(),
431 caster: Arc::new(|s| s.downcast_mut().expect("invalid cast")),
432 }
433 }
434
435 pub fn has_pending_requests(&self) -> bool {
437 self.req_queue.lock().incoming.has_pending()
438 }
439
440 pub fn begin_panic(&self) {
442 self.req_queue.lock().begin_panic();
443 }
444
445 pub fn send_event<T: std::any::Any + Send + 'static>(&self, event: T) {
447 self.sender.send_event(event);
448 }
449
450 #[cfg(feature = "lsp")]
452 pub fn complete_lsp_request<S: Any>(&self, service: &mut S, response: lsp::Response) {
453 let mut req_queue = self.req_queue.lock();
454 let Some(handler) = req_queue.outgoing.complete(response.id.clone()) else {
455 log::warn!("received response for unknown request");
456 return;
457 };
458 drop(req_queue);
459 handler(service, response.into())
460 }
461
462 #[cfg(feature = "dap")]
464 pub fn complete_dap_request<S: Any>(&self, service: &mut S, response: dap::Response) {
465 let mut req_queue = self.req_queue.lock();
466 let Some(handler) = req_queue
467 .outgoing
468 .complete((response.request_seq as i32).into())
470 else {
471 log::warn!("received response for unknown request");
472 return;
473 };
474 drop(req_queue);
475 handler(service, response.into())
476 }
477
478 pub fn register_request(&self, method: &str, id: &RequestId, received_at: Time) {
480 let mut req_queue = self.req_queue.lock();
481 self.hook.start_request(id, method);
482 req_queue
483 .incoming
484 .register(id.clone(), (method.to_owned(), received_at));
485 }
486
487 fn respond_result(&self, id: RequestId, result: LspResult<JsonValue>) {
488 let req_id = id.clone();
489 let msg: Message = match (self.msg_kind, result) {
490 #[cfg(feature = "lsp")]
491 (MessageKind::Lsp, res) => lsp::Response::new(id, res).into(),
492 #[cfg(feature = "dap")]
493 (MessageKind::Dap, Ok(resp)) => dap::Response::success(RequestId::dap(id), resp).into(),
494 #[cfg(feature = "dap")]
495 (MessageKind::Dap, Err(e)) => {
496 dap::Response::error(RequestId::dap(id), Some(e.message), None).into()
497 }
498 };
499
500 self.respond(req_id, msg);
501 }
502
503 pub fn respond(&self, id: RequestId, response: Message) {
505 let mut req_queue = self.req_queue.lock();
506 let Some((method, received_at)) = req_queue.incoming.complete(&id) else {
507 return;
508 };
509
510 self.hook.stop_request(&id, &method, received_at);
511
512 let delay = tinymist_std::time::now().duration_since(received_at);
513 match delay {
514 Ok(delay) => {
515 if delay.as_secs() > 10 {
516 let worst_outgoing =
517 req_queue.incoming.pending().max_by_key(|(_, data)| data.1);
518 let worst_case = if let Some((id, (method, since))) = worst_outgoing {
519 let duration = tinymist_std::time::now().duration_since(*since);
520 format!(", worst case: req({method:?}, {id:?}) - {duration:?}")
521 } else {
522 String::new()
523 };
524 log::warn!(
525 "request {id:?} is completed after {delay:?}, pending incoming requests: {:?}, pending outgoing requests: {:?}{worst_case}",
526 req_queue.incoming,
527 req_queue.outgoing
528 );
529 }
530 }
531 Err(err) => {
532 log::error!("failed to get delay for request {id:?}: {err:?}");
533 }
534 }
535
536 self.sender.send_message(response);
537 }
538}
539
540impl LspClient {
541 pub async fn schedule_tail(self, req_id: RequestId, resp: ScheduleResult) {
544 match resp {
545 Ok(MaybeDone::Done(result)) => {
546 self.respond_result(req_id, result);
547 }
548 Ok(MaybeDone::Future(result)) => {
549 self.respond_result(req_id, result.await);
550 }
551 Ok(MaybeDone::Gone) => {
552 log::warn!("response for request({req_id:?}) already taken");
553 self.respond_result(req_id, Err(internal_error("response already taken")));
554 }
555 Err(err) => {
556 self.respond_result(req_id, Err(err));
557 }
558 }
559 }
560}
561
562pub trait LsHook: fmt::Debug + Send + Sync {
564 fn start_request(&self, req_id: &RequestId, method: &str);
566 fn stop_request(&self, req_id: &RequestId, method: &str, received_at: Time);
568 fn start_notification(&self, track_id: i32, method: &str);
570 fn stop_notification(
572 &self,
573 track_id: i32,
574 method: &str,
575 received_at: Time,
576 result: LspResult<()>,
577 );
578}
579
580impl LsHook for () {
581 fn start_request(&self, req_id: &RequestId, method: &str) {
582 log::info!("handling {method} - ({req_id})");
583 }
584
585 fn stop_request(&self, req_id: &RequestId, method: &str, received_at: Time) {
586 let duration = received_at.elapsed();
587 log::info!("handled {method} - ({req_id}) in {duration:0.2?}");
588 }
589
590 fn start_notification(&self, track_id: i32, method: &str) {
591 log::info!("notifying ({track_id}) - {method}");
592 }
593
594 fn stop_notification(
595 &self,
596 track_id: i32,
597 method: &str,
598 received_at: Time,
599 result: LspResult<()>,
600 ) {
601 let request_duration = received_at.elapsed();
602 if let Err(err) = result {
603 log::error!(
604 "notify ({track_id}) - {method} failed in {request_duration:0.2?}: {err:?}"
605 );
606 } else {
607 log::info!("notify ({track_id}) - {method} succeeded in {request_duration:0.2?}");
608 }
609 }
610}
611
612type AsyncHandler<S, T, R> = fn(srv: &mut S, args: T) -> SchedulableResponse<R>;
613type RawHandler<S, T> = fn(srv: &mut S, args: T) -> ScheduleResult;
614type BoxPureHandler<S, T> = Box<dyn Fn(&mut S, T) -> LspResult<()>>;
615type BoxHandler<S, T> = Box<dyn Fn(&mut S, T) -> SchedulableResponse<JsonValue>>;
616type ExecuteCmdMap<S> = HashMap<&'static str, BoxHandler<S, Vec<JsonValue>>>;
617type RegularCmdMap<S> = HashMap<&'static str, BoxHandler<S, JsonValue>>;
618type NotifyCmdMap<S> = HashMap<&'static str, BoxPureHandler<S, JsonValue>>;
619type ResourceMap<S> = HashMap<ImmutPath, BoxHandler<S, Vec<JsonValue>>>;
620type MayInitBoxHandler<A, S, T> =
621 Box<dyn for<'a> Fn(ServiceState<'a, A, S>, &LspClient, T) -> anyhow::Result<()>>;
622type EventMap<A, S> = HashMap<core::any::TypeId, MayInitBoxHandler<A, S, Event>>;
623
624pub trait Initializer {
626 type I: for<'de> serde::Deserialize<'de>;
628 type S;
630
631 fn initialize(self, req: Self::I) -> (Self::S, AnySchedulableResponse);
635}
636
637#[cfg(feature = "lsp")]
639pub type LspBuilder<Args> = LsBuilder<LspMessage, Args>;
640#[cfg(feature = "dap")]
642pub type DapBuilder<Args> = LsBuilder<DapMessage, Args>;
643
644pub struct LsBuilder<M, Args: Initializer> {
646 pub args: Args,
648 pub client: LspClient,
650 pub events: EventMap<Args, Args::S>,
652 pub command_handlers: ExecuteCmdMap<Args::S>,
654 pub notif_handlers: NotifyCmdMap<Args::S>,
656 pub req_handlers: RegularCmdMap<Args::S>,
658 pub resource_handlers: ResourceMap<Args::S>,
660 _marker: std::marker::PhantomData<M>,
661}
662
663impl<M, Args: Initializer> LsBuilder<M, Args>
664where
665 Args::S: 'static,
666{
667 pub fn new(args: Args, client: LspClient) -> Self {
669 Self {
670 args,
671 client,
672 events: EventMap::new(),
673 command_handlers: ExecuteCmdMap::new(),
674 notif_handlers: NotifyCmdMap::new(),
675 req_handlers: RegularCmdMap::new(),
676 resource_handlers: ResourceMap::new(),
677 _marker: std::marker::PhantomData,
678 }
679 }
680
681 pub fn with_event<T: std::any::Any>(
683 mut self,
684 ins: &T,
685 handler: impl for<'a> Fn(ServiceState<'a, Args, Args::S>, T) -> anyhow::Result<()> + 'static,
686 ) -> Self {
687 self.events.insert(
688 ins.type_id(),
689 Box::new(move |s, _client, req| handler(s, *req.downcast().unwrap())),
690 );
691 self
692 }
693
694 pub fn with_resource(
696 mut self,
697 path: &'static str,
698 handler: fn(&mut Args::S, Vec<JsonValue>) -> AnySchedulableResponse,
699 ) -> Self {
700 self.resource_handlers
701 .insert(Path::new(path).into(), Box::new(handler));
702 self
703 }
704
705 pub fn build(self) -> LsDriver<M, Args> {
707 LsDriver {
708 state: State::Uninitialized(Some(Box::new(self.args))),
709 next_not_id: AtomicI32::new(1),
710 events: self.events,
711 client: self.client,
712 commands: self.command_handlers,
713 notifications: self.notif_handlers,
714 requests: self.req_handlers,
715 resources: self.resource_handlers,
716 _marker: std::marker::PhantomData,
717 }
718 }
719}
720
721pub enum ServiceState<'a, A, S> {
723 Uninitialized(Option<&'a mut A>),
725 Ready(&'a mut S),
727}
728
729impl<A, S> ServiceState<'_, A, S> {
730 pub fn ready(&mut self) -> Option<&mut S> {
732 match self {
733 ServiceState::Ready(s) => Some(s),
734 _ => None,
735 }
736 }
737}
738
739#[derive(Debug, Clone, PartialEq, Eq)]
740enum State<Args, S> {
741 Uninitialized(Option<Box<Args>>),
742 Initializing(S),
743 Ready(S),
744 ShuttingDown,
745}
746
747impl<Args, S> State<Args, S> {
748 fn opt(&self) -> Option<&S> {
749 match &self {
750 State::Ready(s) => Some(s),
751 _ => None,
752 }
753 }
754
755 fn opt_mut(&mut self) -> Option<&mut S> {
756 match self {
757 State::Ready(s) => Some(s),
758 _ => None,
759 }
760 }
761}
762
763pub struct LsDriver<M, Args: Initializer> {
765 state: State<Args, Args::S>,
767 pub client: LspClient,
769 pub next_not_id: AtomicI32,
771
772 pub events: EventMap<Args, Args::S>,
775 pub commands: ExecuteCmdMap<Args::S>,
777 pub notifications: NotifyCmdMap<Args::S>,
779 pub requests: RegularCmdMap<Args::S>,
781 pub resources: ResourceMap<Args::S>,
783 _marker: std::marker::PhantomData<M>,
784}
785
786impl<M, Args: Initializer> LsDriver<M, Args> {
787 pub fn state(&self) -> Option<&Args::S> {
789 self.state.opt()
790 }
791
792 pub fn state_mut(&mut self) -> Option<&mut Args::S> {
794 self.state.opt_mut()
795 }
796
797 pub fn ready(&mut self, params: Args::I) -> AnySchedulableResponse {
799 let args = match &mut self.state {
800 State::Uninitialized(args) => args,
801 _ => return just_result(Err(invalid_request("server is already initialized"))),
802 };
803
804 let args = args.take().expect("already initialized");
805 let (s, res) = args.initialize(params);
806 self.state = State::Ready(s);
807
808 res
809 }
810
811 pub fn get_resources(&mut self, args: Vec<JsonValue>) -> ScheduleResult {
814 let s = self.state.opt_mut().ok_or_else(not_initialized)?;
815
816 let path =
817 from_value::<PathBuf>(args[0].clone()).map_err(|e| invalid_params(e.to_string()))?;
818
819 let Some(handler) = self.resources.get(path.as_path()) else {
820 log::error!("asked for unknown resource: {path:?}");
821 return Err(method_not_found());
822 };
823
824 handler(s, args)
826 }
827}
828
829pub fn just_ok<T, E>(res: T) -> Result<ResponseFuture<Result<T, E>>, E> {
831 Ok(futures::future::MaybeDone::Done(Ok(res)))
832}
833
834pub fn just_result<T, E>(res: Result<T, E>) -> Result<ResponseFuture<Result<T, E>>, E> {
836 Ok(futures::future::MaybeDone::Done(res))
837}
838
839pub fn just_future<T, E>(
841 fut: impl std::future::Future<Output = Result<T, E>> + Send + 'static,
842) -> Result<ResponseFuture<Result<T, E>>, E> {
843 Ok(futures::future::MaybeDone::Future(Box::pin(fut)))
844}
845
846pub fn invalid_params(msg: impl fmt::Display) -> ResponseError {
848 resp_err(ErrorCode::InvalidParams, msg)
849}
850
851pub fn internal_error(msg: impl fmt::Display) -> ResponseError {
853 resp_err(ErrorCode::InternalError, msg)
854}
855
856pub fn not_initialized() -> ResponseError {
858 resp_err(ErrorCode::ServerNotInitialized, "not initialized yet")
859}
860
861pub fn method_not_found() -> ResponseError {
863 resp_err(ErrorCode::MethodNotFound, "method not found")
864}
865
866pub fn invalid_request(msg: impl fmt::Display) -> ResponseError {
868 resp_err(ErrorCode::InvalidRequest, msg)
869}
870
871fn from_json<T: serde::de::DeserializeOwned>(json: JsonValue) -> LspResult<T> {
872 serde_json::from_value(json).map_err(invalid_request)
873}
874
875pub fn erased_response<T: Serialize + 'static>(resp: SchedulableResponse<T>) -> ScheduleResult {
877 fn map_respond_result<T: Serialize>(result: LspResult<T>) -> LspResult<JsonValue> {
879 result.and_then(|t| serde_json::to_value(t).map_err(internal_error))
880 }
881
882 let resp = resp?;
883
884 use futures::future::MaybeDone::*;
885 Ok(match resp {
886 Done(result) => MaybeDone::Done(map_respond_result(result)),
887 Future(fut) => MaybeDone::Future(Box::pin(async move { map_respond_result(fut.await) })),
888 Gone => {
889 log::warn!("response already taken");
890 MaybeDone::Done(Err(internal_error("response already taken")))
891 }
892 })
893}
894
895fn resp_err(code: ErrorCode, msg: impl fmt::Display) -> ResponseError {
896 ResponseError {
897 code: code as i32,
898 message: msg.to_string(),
899 data: None,
900 }
901}