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;
14#[cfg(feature = "web")]
15use std::sync::atomic::AtomicU32;
16use std::sync::{Arc, Weak};
17
18use futures::future::MaybeDone;
19use parking_lot::Mutex;
20use serde::Serialize;
21use serde_json::{Value as JsonValue, from_value};
22use tinymist_std::time::Instant;
23
24use crate::msg::*;
25use crate::req_queue;
26use crate::*;
27
28type ImmutPath = Arc<Path>;
29
30pub type ResponseFuture<T> = MaybeDone<Pin<Box<dyn std::future::Future<Output = T> + Send>>>;
32pub type LspResponseFuture<T> = LspResult<ResponseFuture<T>>;
34pub type SchedulableResponse<T> = LspResponseFuture<LspResult<T>>;
36pub type AnySchedulableResponse = SchedulableResponse<JsonValue>;
38pub type ScheduleResult = AnySchedulableResponse;
40pub type ScheduledResult = LspResult<Option<()>>;
46
47pub type ConnectionTx = TConnectionTx<Message>;
49pub type ConnectionRx = TConnectionRx<Message>;
51
52#[derive(Debug, Clone)]
54pub struct TConnectionTx<M> {
55 pub event: crossbeam_channel::Sender<Event>,
57 pub lsp: crossbeam_channel::Sender<Message>,
59 pub(crate) marker: std::marker::PhantomData<M>,
60}
61
62#[derive(Debug, Clone)]
64pub struct TConnectionRx<M> {
65 pub event: crossbeam_channel::Receiver<Event>,
67 pub lsp: crossbeam_channel::Receiver<Message>,
69 pub(crate) marker: std::marker::PhantomData<M>,
70}
71
72impl<M: TryFrom<Message, Error = anyhow::Error>> TConnectionRx<M> {
73 pub fn recv(&self) -> anyhow::Result<EventOrMessage<M>> {
75 crossbeam_channel::select_biased! {
76 recv(self.lsp) -> msg => Ok(EventOrMessage::Msg(msg?.try_into()?)),
77 recv(self.event) -> event => Ok(event.map(EventOrMessage::Evt)?),
78 }
79 }
80}
81
82pub enum EventOrMessage<M> {
84 Evt(Event),
86 Msg(M),
88}
89
90pub struct Connection<M> {
92 pub sender: TConnectionTx<M>,
94 pub receiver: TConnectionRx<M>,
96}
97
98impl<M: TryFrom<Message, Error = anyhow::Error>> From<Connection<Message>> for Connection<M> {
99 fn from(conn: Connection<Message>) -> Self {
100 Self {
101 sender: TConnectionTx {
102 event: conn.sender.event,
103 lsp: conn.sender.lsp,
104 marker: std::marker::PhantomData,
105 },
106 receiver: TConnectionRx {
107 event: conn.receiver.event,
108 lsp: conn.receiver.lsp,
109 marker: std::marker::PhantomData,
110 },
111 }
112 }
113}
114
115impl<M: TryFrom<Message, Error = anyhow::Error>> From<TConnectionTx<M>> for ConnectionTx {
116 fn from(conn: TConnectionTx<M>) -> Self {
117 Self {
118 event: conn.event,
119 lsp: conn.lsp,
120 marker: std::marker::PhantomData,
121 }
122 }
123}
124
125type AnyCaster<S> = Arc<dyn Fn(&mut dyn Any) -> &mut S + Send + Sync>;
126
127pub struct TypedLspClient<S> {
129 client: LspClient,
130 caster: AnyCaster<S>,
131}
132
133impl<S> TypedLspClient<S> {
134 pub fn to_untyped(self) -> LspClient {
136 self.client
137 }
138}
139
140impl<S: 'static> TypedLspClient<S> {
141 pub fn untyped(&self) -> &LspClient {
143 &self.client
144 }
145
146 pub fn cast<T: 'static>(&self, f: fn(&mut S) -> &mut T) -> TypedLspClient<T> {
148 let caster = self.caster.clone();
149 TypedLspClient {
150 client: self.client.clone(),
151 caster: Arc::new(move |s| f(caster(s))),
152 }
153 }
154
155 pub fn send_event<T: std::any::Any + Send + 'static>(&self, event: T) {
157 self.sender.send_event(event);
158 }
159}
160
161impl<S> Clone for TypedLspClient<S> {
162 fn clone(&self) -> Self {
163 Self {
164 client: self.client.clone(),
165 caster: self.caster.clone(),
166 }
167 }
168}
169
170impl<S> std::ops::Deref for TypedLspClient<S> {
171 type Target = LspClient;
172
173 fn deref(&self) -> &Self::Target {
174 &self.client
175 }
176}
177
178#[derive(Debug, Clone)]
183pub struct LspClientRoot {
184 weak: LspClient,
185 _strong: Arc<ConnectionTx>,
186}
187
188impl LspClientRoot {
189 pub fn new<M: TryFrom<Message, Error = anyhow::Error> + GetMessageKind>(
191 handle: tokio::runtime::Handle,
192 sender: TConnectionTx<M>,
193 ) -> Self {
194 let _strong = Arc::new(sender.into());
195 let weak = LspClient {
196 handle,
197 msg_kind: M::MESSAGE_KIND,
198 sender: TransportHost::System(SystemTransportSender {
199 sender: Arc::downgrade(&_strong),
200 }),
201 req_queue: Arc::new(Mutex::new(ReqQueue::default())),
202
203 hook: Arc::new(()),
204 };
205 Self { weak, _strong }
206 }
207
208 #[cfg(feature = "web")]
210 pub fn new_js(handle: tokio::runtime::Handle, transport: JsTransportSender) -> Self {
211 let dummy = dummy_transport::<LspMessage>();
212
213 let _strong = Arc::new(dummy.sender.into());
214 let weak = LspClient {
215 handle,
216 msg_kind: LspMessage::MESSAGE_KIND,
217 sender: TransportHost::Js(transport),
218 req_queue: Arc::new(Mutex::new(ReqQueue::default())),
219
220 hook: Arc::new(()),
221 };
222 Self { weak, _strong }
223 }
224
225 pub fn with_hook(mut self, hook: Arc<dyn LsHook>) -> Self {
227 self.weak.hook = hook;
228 self
229 }
230
231 pub fn weak(&self) -> LspClient {
233 self.weak.clone()
234 }
235}
236
237type ReqHandler = Box<dyn for<'a> FnOnce(&'a mut dyn Any, LspOrDapResponse) + Send + Sync>;
238type ReqQueue = req_queue::ReqQueue<(String, Instant), ReqHandler>;
239
240#[derive(Debug, Clone)]
241enum TransportHost {
242 System(SystemTransportSender),
243 #[cfg(feature = "web")]
244 Js(JsTransportSender),
245}
246
247#[derive(Debug, Clone)]
248struct SystemTransportSender {
249 pub(crate) sender: Weak<ConnectionTx>,
250}
251
252#[cfg(feature = "web")]
254#[derive(Debug, Clone)]
255pub struct JsTransportSender {
256 event_id: Arc<AtomicU32>,
257 events: Arc<Mutex<HashMap<u32, Event>>>,
258 pub(crate) sender_event: js_sys::Function,
259 pub(crate) sender_request: js_sys::Function,
260 pub(crate) sender_notification: js_sys::Function,
261}
262
263#[cfg(feature = "web")]
264impl JsTransportSender {
265 pub fn new(
267 sender_event: js_sys::Function,
268 sender_request: js_sys::Function,
269 sender_notification: js_sys::Function,
270 ) -> Self {
271 Self {
272 event_id: Arc::new(AtomicU32::new(0)),
273 events: Arc::new(Mutex::new(HashMap::new())),
274 sender_event,
275 sender_request,
276 sender_notification,
277 }
278 }
279}
280
281#[cfg(feature = "web")]
282unsafe impl Send for TransportHost {}
285
286#[cfg(feature = "web")]
287unsafe impl Sync for TransportHost {}
290
291impl TransportHost {
292 pub fn send_event<T: std::any::Any + Send + 'static>(&self, event: T) {
294 match self {
295 TransportHost::System(host) => {
296 let Some(sender) = host.sender.upgrade() else {
297 log::warn!("failed to send request: connection closed");
298 return;
299 };
300
301 if let Err(res) = sender.event.send(Box::new(event)) {
302 log::warn!("failed to send event: {res:?}");
303 }
304 }
305 #[cfg(feature = "web")]
306 TransportHost::Js(host) => {
307 let event_id = {
308 let event_id = host
309 .event_id
310 .fetch_add(1, std::sync::atomic::Ordering::SeqCst);
311 let mut lg = host.events.lock();
312 lg.insert(event_id, Box::new(event));
313 js_sys::Number::from(event_id)
314 };
315 if let Err(err) = host
316 .sender_event
317 .call1(&wasm_bindgen::JsValue::UNDEFINED, &event_id.into())
318 {
319 log::error!("failed to send event: {err:?}");
320 }
321 }
322 }
323 }
324
325 pub fn send_message(&self, response: Message) {
326 match self {
327 TransportHost::System(host) => {
328 let Some(sender) = host.sender.upgrade() else {
329 log::warn!("failed to send response: connection closed");
330 return;
331 };
332 if let Err(res) = sender.lsp.send(response) {
333 log::warn!("failed to send response: {res:?}");
334 }
335 }
336 #[cfg(feature = "web")]
337 TransportHost::Js(host) => match response {
338 #[cfg(feature = "lsp")]
339 Message::Lsp(lsp::Message::Request(req)) => {
340 let msg = to_js_value(&req).expect("failed to serialize request to js value");
341 if let Err(err) = host
342 .sender_request
343 .call1(&wasm_bindgen::JsValue::UNDEFINED, &msg)
344 {
345 log::error!("failed to send request: {err:?}");
346 }
347 }
348 #[cfg(feature = "lsp")]
349 Message::Lsp(lsp::Message::Notification(req)) => {
350 let msg = to_js_value(&req).expect("failed to serialize request to js value");
351 if let Err(err) = host
352 .sender_notification
353 .call1(&wasm_bindgen::JsValue::UNDEFINED, &msg)
354 {
355 log::error!("failed to send request: {err:?}");
356 }
357 }
358 #[cfg(feature = "lsp")]
359 Message::Lsp(lsp::Message::Response(req)) => {
360 panic!("unexpected response to js world: {req:?}");
361 }
362 #[cfg(feature = "dap")]
363 Message::Dap(dap::Message::Request(req)) => {
364 let msg = to_js_value(&req).expect("failed to serialize request to js value");
365 if let Err(err) = host
366 .sender_request
367 .call1(&wasm_bindgen::JsValue::UNDEFINED, &msg)
368 {
369 log::error!("failed to send request: {err:?}");
370 }
371 }
372 #[cfg(feature = "dap")]
373 Message::Dap(dap::Message::Event(req)) => {
374 let msg = to_js_value(&req).expect("failed to serialize request to js value");
375 if let Err(err) = host
376 .sender_notification
377 .call1(&wasm_bindgen::JsValue::UNDEFINED, &msg)
378 {
379 log::error!("failed to send request: {err:?}");
380 }
381 }
382 #[cfg(feature = "dap")]
383 Message::Dap(dap::Message::Response(req)) => {
384 panic!("unexpected response to js world: {req:?}");
385 }
386 },
387 }
388 }
389}
390
391#[cfg(feature = "web")]
394fn to_js_value<T: serde::Serialize>(
395 value: &T,
396) -> Result<wasm_bindgen::JsValue, serde_wasm_bindgen::Error> {
397 value.serialize(&serde_wasm_bindgen::Serializer::new().serialize_maps_as_objects(true))
398}
399
400#[derive(Debug, Clone)]
402pub struct LspClient {
403 pub handle: tokio::runtime::Handle,
405
406 pub(crate) msg_kind: MessageKind,
407 sender: TransportHost,
408 pub(crate) req_queue: Arc<Mutex<ReqQueue>>,
409
410 pub(crate) hook: Arc<dyn LsHook>,
411}
412
413impl LspClient {
414 pub fn untyped(&self) -> &Self {
416 self
417 }
418
419 pub fn to_typed<S: Any>(&self) -> TypedLspClient<S> {
421 TypedLspClient {
422 client: self.clone(),
423 caster: Arc::new(|s| s.downcast_mut().expect("invalid cast")),
424 }
425 }
426
427 pub fn has_pending_requests(&self) -> bool {
429 self.req_queue.lock().incoming.has_pending()
430 }
431
432 pub fn begin_panic(&self) {
434 self.req_queue.lock().begin_panic();
435 }
436
437 pub fn send_event<T: std::any::Any + Send + 'static>(&self, event: T) {
439 self.sender.send_event(event);
440 }
441
442 #[cfg(feature = "lsp")]
444 pub fn complete_lsp_request<S: Any>(&self, service: &mut S, response: lsp::Response) {
445 let mut req_queue = self.req_queue.lock();
446 let Some(handler) = req_queue.outgoing.complete(response.id.clone()) else {
447 log::warn!("received response for unknown request");
448 return;
449 };
450 drop(req_queue);
451 handler(service, response.into())
452 }
453
454 #[cfg(feature = "dap")]
456 pub fn complete_dap_request<S: Any>(&self, service: &mut S, response: dap::Response) {
457 let mut req_queue = self.req_queue.lock();
458 let Some(handler) = req_queue
459 .outgoing
460 .complete((response.request_seq as i32).into())
462 else {
463 log::warn!("received response for unknown request");
464 return;
465 };
466 drop(req_queue);
467 handler(service, response.into())
468 }
469
470 pub fn register_request(&self, method: &str, id: &RequestId, received_at: Instant) {
472 let mut req_queue = self.req_queue.lock();
473 self.hook.start_request(id, method);
474 req_queue
475 .incoming
476 .register(id.clone(), (method.to_owned(), received_at));
477 }
478
479 fn respond_result(&self, id: RequestId, result: LspResult<JsonValue>) {
480 let req_id = id.clone();
481 let msg: Message = match (self.msg_kind, result) {
482 #[cfg(feature = "lsp")]
483 (MessageKind::Lsp, res) => lsp::Response::new(id, res).into(),
484 #[cfg(feature = "dap")]
485 (MessageKind::Dap, Ok(resp)) => dap::Response::success(RequestId::dap(id), resp).into(),
486 #[cfg(feature = "dap")]
487 (MessageKind::Dap, Err(e)) => {
488 dap::Response::error(RequestId::dap(id), Some(e.message), None).into()
489 }
490 };
491
492 self.respond(req_id, msg);
493 }
494
495 pub fn respond(&self, id: RequestId, response: Message) {
497 let mut req_queue = self.req_queue.lock();
498 let Some((method, received_at)) = req_queue.incoming.complete(&id) else {
499 return;
500 };
501
502 self.hook.stop_request(&id, &method, received_at);
503
504 self.sender.send_message(response);
505 }
506}
507
508impl LspClient {
509 pub async fn schedule_tail(self, req_id: RequestId, resp: ScheduleResult) {
512 match resp {
513 Ok(MaybeDone::Done(result)) => {
514 self.respond_result(req_id, result);
515 }
516 Ok(MaybeDone::Future(result)) => {
517 self.respond_result(req_id, result.await);
518 }
519 Ok(MaybeDone::Gone) => {
520 log::warn!("response for request({req_id:?}) already taken");
521 self.respond_result(req_id, Err(internal_error("response already taken")));
522 }
523 Err(err) => {
524 self.respond_result(req_id, Err(err));
525 }
526 }
527 }
528}
529
530pub trait LsHook: fmt::Debug + Send + Sync {
532 fn start_request(&self, req_id: &RequestId, method: &str);
534 fn stop_request(&self, req_id: &RequestId, method: &str, received_at: Instant);
536 fn start_notification(&self, method: &str);
538 fn stop_notification(&self, method: &str, received_at: Instant, result: LspResult<()>);
540}
541
542impl LsHook for () {
543 fn start_request(&self, req_id: &RequestId, method: &str) {
544 log::info!("handling {method} - ({req_id})");
545 }
546
547 fn stop_request(&self, req_id: &RequestId, method: &str, received_at: Instant) {
548 let duration = received_at.elapsed();
549 log::info!("handled {method} - ({req_id}) in {duration:0.2?}");
550 }
551
552 fn start_notification(&self, method: &str) {
553 log::info!("notifying {method}");
554 }
555
556 fn stop_notification(&self, method: &str, received_at: Instant, result: LspResult<()>) {
557 let request_duration = received_at.elapsed();
558 if let Err(err) = result {
559 log::error!("notify {method} failed in {request_duration:0.2?}: {err:?}");
560 } else {
561 log::info!("notify {method} succeeded in {request_duration:0.2?}");
562 }
563 }
564}
565
566type AsyncHandler<S, T, R> = fn(srv: &mut S, args: T) -> SchedulableResponse<R>;
567type RawHandler<S, T> = fn(srv: &mut S, args: T) -> ScheduleResult;
568type BoxPureHandler<S, T> = Box<dyn Fn(&mut S, T) -> LspResult<()>>;
569type BoxHandler<S, T> = Box<dyn Fn(&mut S, T) -> SchedulableResponse<JsonValue>>;
570type ExecuteCmdMap<S> = HashMap<&'static str, BoxHandler<S, Vec<JsonValue>>>;
571type RegularCmdMap<S> = HashMap<&'static str, BoxHandler<S, JsonValue>>;
572type NotifyCmdMap<S> = HashMap<&'static str, BoxPureHandler<S, JsonValue>>;
573type ResourceMap<S> = HashMap<ImmutPath, BoxHandler<S, Vec<JsonValue>>>;
574type MayInitBoxHandler<A, S, T> =
575 Box<dyn for<'a> Fn(ServiceState<'a, A, S>, &LspClient, T) -> anyhow::Result<()>>;
576type EventMap<A, S> = HashMap<core::any::TypeId, MayInitBoxHandler<A, S, Event>>;
577
578pub trait Initializer {
580 type I: for<'de> serde::Deserialize<'de>;
582 type S;
584
585 fn initialize(self, req: Self::I) -> (Self::S, AnySchedulableResponse);
589}
590
591#[cfg(feature = "lsp")]
593pub type LspBuilder<Args> = LsBuilder<LspMessage, Args>;
594#[cfg(feature = "dap")]
596pub type DapBuilder<Args> = LsBuilder<DapMessage, Args>;
597
598pub struct LsBuilder<M, Args: Initializer> {
600 pub args: Args,
602 pub client: LspClient,
604 pub events: EventMap<Args, Args::S>,
606 pub command_handlers: ExecuteCmdMap<Args::S>,
608 pub notif_handlers: NotifyCmdMap<Args::S>,
610 pub req_handlers: RegularCmdMap<Args::S>,
612 pub resource_handlers: ResourceMap<Args::S>,
614 _marker: std::marker::PhantomData<M>,
615}
616
617impl<M, Args: Initializer> LsBuilder<M, Args>
618where
619 Args::S: 'static,
620{
621 pub fn new(args: Args, client: LspClient) -> Self {
623 Self {
624 args,
625 client,
626 events: EventMap::new(),
627 command_handlers: ExecuteCmdMap::new(),
628 notif_handlers: NotifyCmdMap::new(),
629 req_handlers: RegularCmdMap::new(),
630 resource_handlers: ResourceMap::new(),
631 _marker: std::marker::PhantomData,
632 }
633 }
634
635 pub fn with_event<T: std::any::Any>(
637 mut self,
638 ins: &T,
639 handler: impl for<'a> Fn(ServiceState<'a, Args, Args::S>, T) -> anyhow::Result<()> + 'static,
640 ) -> Self {
641 self.events.insert(
642 ins.type_id(),
643 Box::new(move |s, _client, req| handler(s, *req.downcast().unwrap())),
644 );
645 self
646 }
647
648 pub fn with_resource(
650 mut self,
651 path: &'static str,
652 handler: fn(&mut Args::S, Vec<JsonValue>) -> AnySchedulableResponse,
653 ) -> Self {
654 self.resource_handlers
655 .insert(Path::new(path).into(), Box::new(handler));
656 self
657 }
658
659 pub fn build(self) -> LsDriver<M, Args> {
661 LsDriver {
662 state: State::Uninitialized(Some(Box::new(self.args))),
663 events: self.events,
664 client: self.client,
665 commands: self.command_handlers,
666 notifications: self.notif_handlers,
667 requests: self.req_handlers,
668 resources: self.resource_handlers,
669 _marker: std::marker::PhantomData,
670 }
671 }
672}
673
674pub enum ServiceState<'a, A, S> {
676 Uninitialized(Option<&'a mut A>),
678 Ready(&'a mut S),
680}
681
682impl<A, S> ServiceState<'_, A, S> {
683 pub fn ready(&mut self) -> Option<&mut S> {
685 match self {
686 ServiceState::Ready(s) => Some(s),
687 _ => None,
688 }
689 }
690}
691
692#[derive(Debug, Clone, PartialEq, Eq)]
693enum State<Args, S> {
694 Uninitialized(Option<Box<Args>>),
695 Initializing(S),
696 Ready(S),
697 ShuttingDown,
698}
699
700impl<Args, S> State<Args, S> {
701 fn opt(&self) -> Option<&S> {
702 match &self {
703 State::Ready(s) => Some(s),
704 _ => None,
705 }
706 }
707
708 fn opt_mut(&mut self) -> Option<&mut S> {
709 match self {
710 State::Ready(s) => Some(s),
711 _ => None,
712 }
713 }
714}
715
716pub struct LsDriver<M, Args: Initializer> {
718 state: State<Args, Args::S>,
720 pub client: LspClient,
722
723 pub events: EventMap<Args, Args::S>,
726 pub commands: ExecuteCmdMap<Args::S>,
728 pub notifications: NotifyCmdMap<Args::S>,
730 pub requests: RegularCmdMap<Args::S>,
732 pub resources: ResourceMap<Args::S>,
734 _marker: std::marker::PhantomData<M>,
735}
736
737impl<M, Args: Initializer> LsDriver<M, Args> {
738 pub fn state(&self) -> Option<&Args::S> {
740 self.state.opt()
741 }
742
743 pub fn state_mut(&mut self) -> Option<&mut Args::S> {
745 self.state.opt_mut()
746 }
747
748 pub fn ready(&mut self, params: Args::I) -> AnySchedulableResponse {
750 let args = match &mut self.state {
751 State::Uninitialized(args) => args,
752 _ => return just_result(Err(invalid_request("server is already initialized"))),
753 };
754
755 let args = args.take().expect("already initialized");
756 let (s, res) = args.initialize(params);
757 self.state = State::Ready(s);
758
759 res
760 }
761
762 pub fn get_resources(&mut self, args: Vec<JsonValue>) -> ScheduleResult {
765 let s = self.state.opt_mut().ok_or_else(not_initialized)?;
766
767 let path =
768 from_value::<PathBuf>(args[0].clone()).map_err(|e| invalid_params(e.to_string()))?;
769
770 let Some(handler) = self.resources.get(path.as_path()) else {
771 log::error!("asked for unknown resource: {path:?}");
772 return Err(method_not_found());
773 };
774
775 handler(s, args)
777 }
778}
779
780pub fn just_ok<T, E>(res: T) -> Result<ResponseFuture<Result<T, E>>, E> {
782 Ok(futures::future::MaybeDone::Done(Ok(res)))
783}
784
785pub fn just_result<T, E>(res: Result<T, E>) -> Result<ResponseFuture<Result<T, E>>, E> {
787 Ok(futures::future::MaybeDone::Done(res))
788}
789
790pub fn just_future<T, E>(
792 fut: impl std::future::Future<Output = Result<T, E>> + Send + 'static,
793) -> Result<ResponseFuture<Result<T, E>>, E> {
794 Ok(futures::future::MaybeDone::Future(Box::pin(fut)))
795}
796
797pub fn invalid_params(msg: impl fmt::Display) -> ResponseError {
799 resp_err(ErrorCode::InvalidParams, msg)
800}
801
802pub fn internal_error(msg: impl fmt::Display) -> ResponseError {
804 resp_err(ErrorCode::InternalError, msg)
805}
806
807pub fn not_initialized() -> ResponseError {
809 resp_err(ErrorCode::ServerNotInitialized, "not initialized yet")
810}
811
812pub fn method_not_found() -> ResponseError {
814 resp_err(ErrorCode::MethodNotFound, "method not found")
815}
816
817pub fn invalid_request(msg: impl fmt::Display) -> ResponseError {
819 resp_err(ErrorCode::InvalidRequest, msg)
820}
821
822fn from_json<T: serde::de::DeserializeOwned>(json: JsonValue) -> LspResult<T> {
823 serde_json::from_value(json).map_err(invalid_request)
824}
825
826pub fn erased_response<T: Serialize + 'static>(resp: SchedulableResponse<T>) -> ScheduleResult {
828 fn map_respond_result<T: Serialize>(result: LspResult<T>) -> LspResult<JsonValue> {
830 result.and_then(|t| serde_json::to_value(t).map_err(internal_error))
831 }
832
833 let resp = resp?;
834
835 use futures::future::MaybeDone::*;
836 Ok(match resp {
837 Done(result) => MaybeDone::Done(map_respond_result(result)),
838 Future(fut) => MaybeDone::Future(Box::pin(async move { map_respond_result(fut.await) })),
839 Gone => {
840 log::warn!("response already taken");
841 MaybeDone::Done(Err(internal_error("response already taken")))
842 }
843 })
844}
845
846fn resp_err(code: ErrorCode, msg: impl fmt::Display) -> ResponseError {
847 ResponseError {
848 code: code as i32,
849 message: msg.to_string(),
850 data: None,
851 }
852}