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, sender: 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 {
218 event_id: Arc::new(AtomicU32::new(0)),
219 events: Arc::new(Mutex::new(HashMap::new())),
220 sender,
221 },
222 req_queue: Arc::new(Mutex::new(ReqQueue::default())),
223
224 hook: Arc::new(()),
225 };
226 Self { weak, _strong }
227 }
228
229 pub fn with_hook(mut self, hook: Arc<dyn LsHook>) -> Self {
231 self.weak.hook = hook;
232 self
233 }
234
235 pub fn weak(&self) -> LspClient {
237 self.weak.clone()
238 }
239}
240
241type ReqHandler = Box<dyn for<'a> FnOnce(&'a mut dyn Any, LspOrDapResponse) + Send + Sync>;
242type ReqQueue = req_queue::ReqQueue<(String, Instant), ReqHandler>;
243
244#[derive(Debug, Clone)]
246pub enum TransportHost {
247 System(SystemTransportSender),
249 #[cfg(feature = "web")]
251 Js {
252 event_id: Arc<AtomicU32>,
254 events: Arc<Mutex<HashMap<u32, Event>>>,
256 sender: JsTransportSender,
258 },
259}
260
261#[derive(Debug, Clone)]
263pub struct SystemTransportSender {
264 pub(crate) sender: Weak<ConnectionTx>,
266}
267
268#[cfg(feature = "web")]
270#[derive(Debug, Clone, serde::Deserialize)]
271#[serde(rename_all = "camelCase")]
272pub struct JsTransportSender {
273 #[serde(with = "serde_wasm_bindgen::preserve")]
274 pub(crate) send_event: js_sys::Function,
275 #[serde(with = "serde_wasm_bindgen::preserve")]
276 pub(crate) send_request: js_sys::Function,
277 #[serde(with = "serde_wasm_bindgen::preserve")]
278 pub(crate) send_notification: js_sys::Function,
279 #[serde(with = "serde_wasm_bindgen::preserve")]
281 pub resolve_fn: js_sys::Function,
282}
283
284#[cfg(feature = "web")]
285unsafe impl Send for TransportHost {}
288
289#[cfg(feature = "web")]
290unsafe impl Sync for TransportHost {}
293
294impl TransportHost {
295 pub fn send_event<T: std::any::Any + Send + 'static>(&self, event: T) {
297 match self {
298 TransportHost::System(host) => {
299 let Some(sender) = host.sender.upgrade() else {
300 log::warn!("failed to send request: connection closed");
301 return;
302 };
303
304 if let Err(res) = sender.event.send(Box::new(event)) {
305 log::warn!("failed to send event: {res:?}");
306 }
307 }
308 #[cfg(feature = "web")]
309 TransportHost::Js {
310 event_id,
311 sender,
312 events,
313 } => {
314 let event_id = {
315 let event_id = event_id.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
316 let mut lg = events.lock();
317 lg.insert(event_id, Box::new(event));
318 js_sys::Number::from(event_id)
319 };
320 if let Err(err) = sender
321 .send_event
322 .call1(&wasm_bindgen::JsValue::UNDEFINED, &event_id.into())
323 {
324 log::error!("failed to send event: {err:?}");
325 }
326 }
327 }
328 }
329
330 pub fn send_message(&self, response: Message) {
332 match self {
333 TransportHost::System(host) => {
334 let Some(sender) = host.sender.upgrade() else {
335 log::warn!("failed to send response: connection closed");
336 return;
337 };
338 if let Err(res) = sender.lsp.send(response) {
339 log::warn!("failed to send response: {res:?}");
340 }
341 }
342 #[cfg(feature = "web")]
343 TransportHost::Js { sender, .. } => match response {
344 #[cfg(feature = "lsp")]
345 Message::Lsp(lsp::Message::Request(req)) => {
346 let msg = to_js_value(&req).expect("failed to serialize request to js value");
347 if let Err(err) = sender
348 .send_request
349 .call1(&wasm_bindgen::JsValue::UNDEFINED, &msg)
350 {
351 log::error!("failed to send request: {err:?}");
352 }
353 }
354 #[cfg(feature = "lsp")]
355 Message::Lsp(lsp::Message::Notification(req)) => {
356 let msg = to_js_value(&req).expect("failed to serialize request to js value");
357 if let Err(err) = sender
358 .send_notification
359 .call1(&wasm_bindgen::JsValue::UNDEFINED, &msg)
360 {
361 log::error!("failed to send request: {err:?}");
362 }
363 }
364 #[cfg(feature = "lsp")]
365 Message::Lsp(lsp::Message::Response(req)) => {
366 panic!("unexpected response to js world: {req:?}");
367 }
368 #[cfg(feature = "dap")]
369 Message::Dap(dap::Message::Request(req)) => {
370 let msg = to_js_value(&req).expect("failed to serialize request to js value");
371 if let Err(err) = sender
372 .send_request
373 .call1(&wasm_bindgen::JsValue::UNDEFINED, &msg)
374 {
375 log::error!("failed to send request: {err:?}");
376 }
377 }
378 #[cfg(feature = "dap")]
379 Message::Dap(dap::Message::Event(req)) => {
380 let msg = to_js_value(&req).expect("failed to serialize request to js value");
381 if let Err(err) = sender
382 .send_notification
383 .call1(&wasm_bindgen::JsValue::UNDEFINED, &msg)
384 {
385 log::error!("failed to send request: {err:?}");
386 }
387 }
388 #[cfg(feature = "dap")]
389 Message::Dap(dap::Message::Response(req)) => {
390 panic!("unexpected response to js world: {req:?}");
391 }
392 },
393 }
394 }
395}
396
397#[cfg(feature = "web")]
400fn to_js_value<T: serde::Serialize>(
401 value: &T,
402) -> Result<wasm_bindgen::JsValue, serde_wasm_bindgen::Error> {
403 value.serialize(&serde_wasm_bindgen::Serializer::new().serialize_maps_as_objects(true))
404}
405
406#[derive(Debug, Clone)]
408pub struct LspClient {
409 pub handle: tokio::runtime::Handle,
411
412 pub(crate) msg_kind: MessageKind,
413 pub sender: TransportHost,
415 pub(crate) req_queue: Arc<Mutex<ReqQueue>>,
416
417 pub(crate) hook: Arc<dyn LsHook>,
418}
419
420impl LspClient {
421 pub fn untyped(&self) -> &Self {
423 self
424 }
425
426 pub fn to_typed<S: Any>(&self) -> TypedLspClient<S> {
428 TypedLspClient {
429 client: self.clone(),
430 caster: Arc::new(|s| s.downcast_mut().expect("invalid cast")),
431 }
432 }
433
434 pub fn has_pending_requests(&self) -> bool {
436 self.req_queue.lock().incoming.has_pending()
437 }
438
439 pub fn begin_panic(&self) {
441 self.req_queue.lock().begin_panic();
442 }
443
444 pub fn send_event<T: std::any::Any + Send + 'static>(&self, event: T) {
446 self.sender.send_event(event);
447 }
448
449 #[cfg(feature = "lsp")]
451 pub fn complete_lsp_request<S: Any>(&self, service: &mut S, response: lsp::Response) {
452 let mut req_queue = self.req_queue.lock();
453 let Some(handler) = req_queue.outgoing.complete(response.id.clone()) else {
454 log::warn!("received response for unknown request");
455 return;
456 };
457 drop(req_queue);
458 handler(service, response.into())
459 }
460
461 #[cfg(feature = "dap")]
463 pub fn complete_dap_request<S: Any>(&self, service: &mut S, response: dap::Response) {
464 let mut req_queue = self.req_queue.lock();
465 let Some(handler) = req_queue
466 .outgoing
467 .complete((response.request_seq as i32).into())
469 else {
470 log::warn!("received response for unknown request");
471 return;
472 };
473 drop(req_queue);
474 handler(service, response.into())
475 }
476
477 pub fn register_request(&self, method: &str, id: &RequestId, received_at: Instant) {
479 let mut req_queue = self.req_queue.lock();
480 self.hook.start_request(id, method);
481 req_queue
482 .incoming
483 .register(id.clone(), (method.to_owned(), received_at));
484 }
485
486 fn respond_result(&self, id: RequestId, result: LspResult<JsonValue>) {
487 let req_id = id.clone();
488 let msg: Message = match (self.msg_kind, result) {
489 #[cfg(feature = "lsp")]
490 (MessageKind::Lsp, res) => lsp::Response::new(id, res).into(),
491 #[cfg(feature = "dap")]
492 (MessageKind::Dap, Ok(resp)) => dap::Response::success(RequestId::dap(id), resp).into(),
493 #[cfg(feature = "dap")]
494 (MessageKind::Dap, Err(e)) => {
495 dap::Response::error(RequestId::dap(id), Some(e.message), None).into()
496 }
497 };
498
499 self.respond(req_id, msg);
500 }
501
502 pub fn respond(&self, id: RequestId, response: Message) {
504 let mut req_queue = self.req_queue.lock();
505 let Some((method, received_at)) = req_queue.incoming.complete(&id) else {
506 return;
507 };
508
509 self.hook.stop_request(&id, &method, received_at);
510
511 self.sender.send_message(response);
512 }
513}
514
515impl LspClient {
516 pub async fn schedule_tail(self, req_id: RequestId, resp: ScheduleResult) {
519 match resp {
520 Ok(MaybeDone::Done(result)) => {
521 self.respond_result(req_id, result);
522 }
523 Ok(MaybeDone::Future(result)) => {
524 self.respond_result(req_id, result.await);
525 }
526 Ok(MaybeDone::Gone) => {
527 log::warn!("response for request({req_id:?}) already taken");
528 self.respond_result(req_id, Err(internal_error("response already taken")));
529 }
530 Err(err) => {
531 self.respond_result(req_id, Err(err));
532 }
533 }
534 }
535}
536
537pub trait LsHook: fmt::Debug + Send + Sync {
539 fn start_request(&self, req_id: &RequestId, method: &str);
541 fn stop_request(&self, req_id: &RequestId, method: &str, received_at: Instant);
543 fn start_notification(&self, method: &str);
545 fn stop_notification(&self, method: &str, received_at: Instant, result: LspResult<()>);
547}
548
549impl LsHook for () {
550 fn start_request(&self, req_id: &RequestId, method: &str) {
551 log::info!("handling {method} - ({req_id})");
552 }
553
554 fn stop_request(&self, req_id: &RequestId, method: &str, received_at: Instant) {
555 let duration = received_at.elapsed();
556 log::info!("handled {method} - ({req_id}) in {duration:0.2?}");
557 }
558
559 fn start_notification(&self, method: &str) {
560 log::info!("notifying {method}");
561 }
562
563 fn stop_notification(&self, method: &str, received_at: Instant, result: LspResult<()>) {
564 let request_duration = received_at.elapsed();
565 if let Err(err) = result {
566 log::error!("notify {method} failed in {request_duration:0.2?}: {err:?}");
567 } else {
568 log::info!("notify {method} succeeded in {request_duration:0.2?}");
569 }
570 }
571}
572
573type AsyncHandler<S, T, R> = fn(srv: &mut S, args: T) -> SchedulableResponse<R>;
574type RawHandler<S, T> = fn(srv: &mut S, args: T) -> ScheduleResult;
575type BoxPureHandler<S, T> = Box<dyn Fn(&mut S, T) -> LspResult<()>>;
576type BoxHandler<S, T> = Box<dyn Fn(&mut S, T) -> SchedulableResponse<JsonValue>>;
577type ExecuteCmdMap<S> = HashMap<&'static str, BoxHandler<S, Vec<JsonValue>>>;
578type RegularCmdMap<S> = HashMap<&'static str, BoxHandler<S, JsonValue>>;
579type NotifyCmdMap<S> = HashMap<&'static str, BoxPureHandler<S, JsonValue>>;
580type ResourceMap<S> = HashMap<ImmutPath, BoxHandler<S, Vec<JsonValue>>>;
581type MayInitBoxHandler<A, S, T> =
582 Box<dyn for<'a> Fn(ServiceState<'a, A, S>, &LspClient, T) -> anyhow::Result<()>>;
583type EventMap<A, S> = HashMap<core::any::TypeId, MayInitBoxHandler<A, S, Event>>;
584
585pub trait Initializer {
587 type I: for<'de> serde::Deserialize<'de>;
589 type S;
591
592 fn initialize(self, req: Self::I) -> (Self::S, AnySchedulableResponse);
596}
597
598#[cfg(feature = "lsp")]
600pub type LspBuilder<Args> = LsBuilder<LspMessage, Args>;
601#[cfg(feature = "dap")]
603pub type DapBuilder<Args> = LsBuilder<DapMessage, Args>;
604
605pub struct LsBuilder<M, Args: Initializer> {
607 pub args: Args,
609 pub client: LspClient,
611 pub events: EventMap<Args, Args::S>,
613 pub command_handlers: ExecuteCmdMap<Args::S>,
615 pub notif_handlers: NotifyCmdMap<Args::S>,
617 pub req_handlers: RegularCmdMap<Args::S>,
619 pub resource_handlers: ResourceMap<Args::S>,
621 _marker: std::marker::PhantomData<M>,
622}
623
624impl<M, Args: Initializer> LsBuilder<M, Args>
625where
626 Args::S: 'static,
627{
628 pub fn new(args: Args, client: LspClient) -> Self {
630 Self {
631 args,
632 client,
633 events: EventMap::new(),
634 command_handlers: ExecuteCmdMap::new(),
635 notif_handlers: NotifyCmdMap::new(),
636 req_handlers: RegularCmdMap::new(),
637 resource_handlers: ResourceMap::new(),
638 _marker: std::marker::PhantomData,
639 }
640 }
641
642 pub fn with_event<T: std::any::Any>(
644 mut self,
645 ins: &T,
646 handler: impl for<'a> Fn(ServiceState<'a, Args, Args::S>, T) -> anyhow::Result<()> + 'static,
647 ) -> Self {
648 self.events.insert(
649 ins.type_id(),
650 Box::new(move |s, _client, req| handler(s, *req.downcast().unwrap())),
651 );
652 self
653 }
654
655 pub fn with_resource(
657 mut self,
658 path: &'static str,
659 handler: fn(&mut Args::S, Vec<JsonValue>) -> AnySchedulableResponse,
660 ) -> Self {
661 self.resource_handlers
662 .insert(Path::new(path).into(), Box::new(handler));
663 self
664 }
665
666 pub fn build(self) -> LsDriver<M, Args> {
668 LsDriver {
669 state: State::Uninitialized(Some(Box::new(self.args))),
670 events: self.events,
671 client: self.client,
672 commands: self.command_handlers,
673 notifications: self.notif_handlers,
674 requests: self.req_handlers,
675 resources: self.resource_handlers,
676 _marker: std::marker::PhantomData,
677 }
678 }
679}
680
681pub enum ServiceState<'a, A, S> {
683 Uninitialized(Option<&'a mut A>),
685 Ready(&'a mut S),
687}
688
689impl<A, S> ServiceState<'_, A, S> {
690 pub fn ready(&mut self) -> Option<&mut S> {
692 match self {
693 ServiceState::Ready(s) => Some(s),
694 _ => None,
695 }
696 }
697}
698
699#[derive(Debug, Clone, PartialEq, Eq)]
700enum State<Args, S> {
701 Uninitialized(Option<Box<Args>>),
702 Initializing(S),
703 Ready(S),
704 ShuttingDown,
705}
706
707impl<Args, S> State<Args, S> {
708 fn opt(&self) -> Option<&S> {
709 match &self {
710 State::Ready(s) => Some(s),
711 _ => None,
712 }
713 }
714
715 fn opt_mut(&mut self) -> Option<&mut S> {
716 match self {
717 State::Ready(s) => Some(s),
718 _ => None,
719 }
720 }
721}
722
723pub struct LsDriver<M, Args: Initializer> {
725 state: State<Args, Args::S>,
727 pub client: LspClient,
729
730 pub events: EventMap<Args, Args::S>,
733 pub commands: ExecuteCmdMap<Args::S>,
735 pub notifications: NotifyCmdMap<Args::S>,
737 pub requests: RegularCmdMap<Args::S>,
739 pub resources: ResourceMap<Args::S>,
741 _marker: std::marker::PhantomData<M>,
742}
743
744impl<M, Args: Initializer> LsDriver<M, Args> {
745 pub fn state(&self) -> Option<&Args::S> {
747 self.state.opt()
748 }
749
750 pub fn state_mut(&mut self) -> Option<&mut Args::S> {
752 self.state.opt_mut()
753 }
754
755 pub fn ready(&mut self, params: Args::I) -> AnySchedulableResponse {
757 let args = match &mut self.state {
758 State::Uninitialized(args) => args,
759 _ => return just_result(Err(invalid_request("server is already initialized"))),
760 };
761
762 let args = args.take().expect("already initialized");
763 let (s, res) = args.initialize(params);
764 self.state = State::Ready(s);
765
766 res
767 }
768
769 pub fn get_resources(&mut self, args: Vec<JsonValue>) -> ScheduleResult {
772 let s = self.state.opt_mut().ok_or_else(not_initialized)?;
773
774 let path =
775 from_value::<PathBuf>(args[0].clone()).map_err(|e| invalid_params(e.to_string()))?;
776
777 let Some(handler) = self.resources.get(path.as_path()) else {
778 log::error!("asked for unknown resource: {path:?}");
779 return Err(method_not_found());
780 };
781
782 handler(s, args)
784 }
785}
786
787pub fn just_ok<T, E>(res: T) -> Result<ResponseFuture<Result<T, E>>, E> {
789 Ok(futures::future::MaybeDone::Done(Ok(res)))
790}
791
792pub fn just_result<T, E>(res: Result<T, E>) -> Result<ResponseFuture<Result<T, E>>, E> {
794 Ok(futures::future::MaybeDone::Done(res))
795}
796
797pub fn just_future<T, E>(
799 fut: impl std::future::Future<Output = Result<T, E>> + Send + 'static,
800) -> Result<ResponseFuture<Result<T, E>>, E> {
801 Ok(futures::future::MaybeDone::Future(Box::pin(fut)))
802}
803
804pub fn invalid_params(msg: impl fmt::Display) -> ResponseError {
806 resp_err(ErrorCode::InvalidParams, msg)
807}
808
809pub fn internal_error(msg: impl fmt::Display) -> ResponseError {
811 resp_err(ErrorCode::InternalError, msg)
812}
813
814pub fn not_initialized() -> ResponseError {
816 resp_err(ErrorCode::ServerNotInitialized, "not initialized yet")
817}
818
819pub fn method_not_found() -> ResponseError {
821 resp_err(ErrorCode::MethodNotFound, "method not found")
822}
823
824pub fn invalid_request(msg: impl fmt::Display) -> ResponseError {
826 resp_err(ErrorCode::InvalidRequest, msg)
827}
828
829fn from_json<T: serde::de::DeserializeOwned>(json: JsonValue) -> LspResult<T> {
830 serde_json::from_value(json).map_err(invalid_request)
831}
832
833pub fn erased_response<T: Serialize + 'static>(resp: SchedulableResponse<T>) -> ScheduleResult {
835 fn map_respond_result<T: Serialize>(result: LspResult<T>) -> LspResult<JsonValue> {
837 result.and_then(|t| serde_json::to_value(t).map_err(internal_error))
838 }
839
840 let resp = resp?;
841
842 use futures::future::MaybeDone::*;
843 Ok(match resp {
844 Done(result) => MaybeDone::Done(map_respond_result(result)),
845 Future(fut) => MaybeDone::Future(Box::pin(async move { map_respond_result(fut.await) })),
846 Gone => {
847 log::warn!("response already taken");
848 MaybeDone::Done(Err(internal_error("response already taken")))
849 }
850 })
851}
852
853fn resp_err(code: ErrorCode, msg: impl fmt::Display) -> ResponseError {
854 ResponseError {
855 code: code as i32,
856 message: msg.to_string(),
857 data: None,
858 }
859}