@@ -15,7 +15,9 @@ use tracing::{debug, error, trace, warn};
1515use crate :: config:: LspServerConfig ;
1616use crate :: error:: { Error , Result } ;
1717use crate :: lsp:: transport:: LspTransport ;
18- use crate :: lsp:: types:: { InboundMessage , JsonRpcRequest , LspNotification , RequestId } ;
18+ use crate :: lsp:: types:: {
19+ InboundMessage , JsonRpcError , JsonRpcRequest , JsonRpcResponse , LspNotification , RequestId ,
20+ } ;
1921
2022/// JSON-RPC protocol version.
2123const JSONRPC_VERSION : & str = "2.0" ;
@@ -371,6 +373,15 @@ impl LspClient {
371373 warn!( "Received response for unknown request ID: {:?}" , response. id) ;
372374 }
373375 }
376+ InboundMessage :: Request ( request) => {
377+ debug!(
378+ "Received server request: {} (id={:?})" ,
379+ request. method, request. id
380+ ) ;
381+ let response = Self :: server_request_response( request) ;
382+ let value = serde_json:: to_value( & response) ?;
383+ transport. send( & value) . await ?;
384+ }
374385 InboundMessage :: Notification ( notification) => {
375386 debug!( "Received notification: {}" , notification. method) ;
376387
@@ -403,6 +414,51 @@ impl LspClient {
403414
404415 Ok ( ( ) )
405416 }
417+
418+ fn server_request_response ( request : JsonRpcRequest ) -> JsonRpcResponse {
419+ match Self :: server_request_result ( & request. method , request. params . as_ref ( ) ) {
420+ Ok ( result) => JsonRpcResponse {
421+ jsonrpc : JSONRPC_VERSION . to_string ( ) ,
422+ id : request. id ,
423+ result : Some ( result) ,
424+ error : None ,
425+ } ,
426+ Err ( error) => JsonRpcResponse {
427+ jsonrpc : JSONRPC_VERSION . to_string ( ) ,
428+ id : request. id ,
429+ result : None ,
430+ error : Some ( error) ,
431+ } ,
432+ }
433+ }
434+
435+ fn server_request_result (
436+ method : & str ,
437+ params : Option < & Value > ,
438+ ) -> std:: result:: Result < Value , JsonRpcError > {
439+ match method {
440+ "client/registerCapability"
441+ | "client/unregisterCapability"
442+ | "workspace/workspaceFolders"
443+ | "window/showMessageRequest" => Ok ( Value :: Null ) ,
444+ "workspace/configuration" => Ok ( Self :: workspace_configuration_result ( params) ) ,
445+ "workspace/applyEdit" => Ok ( serde_json:: json!( { "applied" : false } ) ) ,
446+ _ => Err ( JsonRpcError {
447+ code : -32601 ,
448+ message : format ! ( "Unhandled server request: {method}" ) ,
449+ data : None ,
450+ } ) ,
451+ }
452+ }
453+
454+ fn workspace_configuration_result ( params : Option < & Value > ) -> Value {
455+ let item_count = params
456+ . and_then ( |value| value. get ( "items" ) )
457+ . and_then ( Value :: as_array)
458+ . map_or ( 0 , Vec :: len) ;
459+
460+ Value :: Array ( vec ! [ Value :: Null ; item_count] )
461+ }
406462}
407463
408464#[ cfg( test) ]
@@ -446,6 +502,52 @@ mod tests {
446502 ) ;
447503 }
448504
505+ #[ test]
506+ fn test_register_capability_request_is_acknowledged ( ) {
507+ let request = JsonRpcRequest {
508+ jsonrpc : JSONRPC_VERSION . to_string ( ) ,
509+ id : RequestId :: String ( "ts1" . to_string ( ) ) ,
510+ method : "client/registerCapability" . to_string ( ) ,
511+ params : Some ( serde_json:: json!( { "registrations" : [ ] } ) ) ,
512+ } ;
513+
514+ let response = LspClient :: server_request_response ( request) ;
515+
516+ assert_eq ! ( response. id, RequestId :: String ( "ts1" . to_string( ) ) ) ;
517+ assert_eq ! ( response. result, Some ( Value :: Null ) ) ;
518+ assert ! ( response. error. is_none( ) ) ;
519+ }
520+
521+ #[ test]
522+ fn test_workspace_configuration_request_returns_null_per_item ( ) {
523+ let result = LspClient :: workspace_configuration_result ( Some ( & serde_json:: json!( {
524+ "items" : [ { "section" : "typescript" } , { "section" : "editor" } ]
525+ } ) ) ) ;
526+
527+ assert_eq ! ( result, serde_json:: json!( [ null, null] ) ) ;
528+ }
529+
530+ #[ test]
531+ fn test_unknown_server_request_returns_method_not_found ( ) {
532+ let request = JsonRpcRequest {
533+ jsonrpc : JSONRPC_VERSION . to_string ( ) ,
534+ id : RequestId :: String ( "unknown-1" . to_string ( ) ) ,
535+ method : "custom/request" . to_string ( ) ,
536+ params : None ,
537+ } ;
538+
539+ let response = LspClient :: server_request_response ( request) ;
540+
541+ assert ! ( response. result. is_none( ) ) ;
542+ match response. error {
543+ Some ( error) => {
544+ assert_eq ! ( error. code, -32601 ) ;
545+ assert_eq ! ( error. message, "Unhandled server request: custom/request" ) ;
546+ }
547+ None => panic ! ( "unknown request should return error" ) ,
548+ }
549+ }
550+
449551 #[ tokio:: test]
450552 async fn test_null_response_handling ( ) {
451553 use crate :: lsp:: types:: { JsonRpcResponse , RequestId } ;
0 commit comments