@@ -451,25 +451,17 @@ pub struct Runnable {
451451 pub label : String ,
452452 #[ serde( skip_serializing_if = "Option::is_none" ) ]
453453 pub location : Option < lsp_types:: LocationLink > ,
454- pub kind : RunnableKind ,
454+ # [ serde ( flatten ) ]
455455 pub args : RunnableArgs ,
456456}
457457
458458#[ derive( Deserialize , Serialize , Debug , Clone ) ]
459- #[ serde( rename_all = "camelCase" ) ]
460- #[ serde( untagged) ]
459+ #[ serde( tag = "kind" , content = "args" , rename_all = "lowercase" ) ]
461460pub enum RunnableArgs {
462461 Cargo ( CargoRunnableArgs ) ,
463462 Shell ( ShellRunnableArgs ) ,
464463}
465464
466- #[ derive( Serialize , Deserialize , Debug , Clone ) ]
467- #[ serde( rename_all = "lowercase" ) ]
468- pub enum RunnableKind {
469- Cargo ,
470- Shell ,
471- }
472-
473465#[ derive( Deserialize , Serialize , Debug , Clone ) ]
474466#[ serde( rename_all = "camelCase" ) ]
475467pub struct CargoRunnableArgs {
@@ -881,3 +873,94 @@ impl Request for GetFailedObligations {
881873 type Result = String ;
882874 const METHOD : & ' static str = "rust-analyzer/getFailedObligations" ;
883875}
876+
877+ #[ cfg( test) ]
878+ mod tests {
879+ use super :: * ;
880+ use serde_json:: json;
881+
882+ #[ test]
883+ fn cargo_runnable_round_trips ( ) {
884+ let runnable = Runnable {
885+ label : "cargo test -p my-crate" . to_owned ( ) ,
886+ location : None ,
887+ args : RunnableArgs :: Cargo ( CargoRunnableArgs {
888+ environment : [ ( "RUSTC_TOOLCHAIN" . to_owned ( ) , "/toolchain" . to_owned ( ) ) ]
889+ . into_iter ( )
890+ . collect ( ) ,
891+ cwd : "/project" . into ( ) ,
892+ override_cargo : None ,
893+ workspace_root : Some ( "/project" . into ( ) ) ,
894+ cargo_args : vec ! [
895+ "test" . into( ) ,
896+ "--package" . into( ) ,
897+ "my-crate" . into( ) ,
898+ "--lib" . into( ) ,
899+ ] ,
900+ executable_args : vec ! [ "my_test" . into( ) , "--exact" . into( ) ] ,
901+ } ) ,
902+ } ;
903+ let expected = json ! ( {
904+ "label" : "cargo test -p my-crate" ,
905+ "kind" : "cargo" ,
906+ "args" : {
907+ "environment" : { "RUSTC_TOOLCHAIN" : "/toolchain" } ,
908+ "cwd" : "/project" ,
909+ "overrideCargo" : null,
910+ "workspaceRoot" : "/project" ,
911+ "cargoArgs" : [ "test" , "--package" , "my-crate" , "--lib" ] ,
912+ "executableArgs" : [ "my_test" , "--exact" ] ,
913+ }
914+ } ) ;
915+
916+ let serialized = serde_json:: to_value ( & runnable) . expect ( "serialized runnable" ) ;
917+ assert_eq ! ( serialized, expected) ;
918+
919+ let deserialized: Runnable =
920+ serde_json:: from_value ( expected) . expect ( "cargo runnable should deserialize" ) ;
921+ let RunnableArgs :: Cargo ( cargo) = & deserialized. args else {
922+ panic ! ( "expected Cargo variant, got {:?}" , deserialized. args) ;
923+ } ;
924+ assert_eq ! ( cargo. cargo_args, vec![ "test" , "--package" , "my-crate" , "--lib" ] ) ;
925+ assert_eq ! ( cargo. executable_args, vec![ "my_test" , "--exact" ] ) ;
926+ }
927+
928+ #[ test]
929+ fn shell_runnable_round_trips ( ) {
930+ let runnable = Runnable {
931+ label : "nextest test_one" . to_owned ( ) ,
932+ location : None ,
933+ args : RunnableArgs :: Shell ( ShellRunnableArgs {
934+ environment : [ ( "RUSTC_TOOLCHAIN" . to_owned ( ) , "/toolchain" . to_owned ( ) ) ]
935+ . into_iter ( )
936+ . collect ( ) ,
937+ cwd : "/project" . into ( ) ,
938+ program : "cargo" . into ( ) ,
939+ args : vec ! [ "nextest" . into( ) , "run" . into( ) , "--package" . into( ) , "my-crate" . into( ) ] ,
940+ } ) ,
941+ } ;
942+ let expected = json ! ( {
943+ "label" : "nextest test_one" ,
944+ "kind" : "shell" ,
945+ "args" : {
946+ "environment" : { "RUSTC_TOOLCHAIN" : "/toolchain" } ,
947+ "cwd" : "/project" ,
948+ "program" : "cargo" ,
949+ "args" : [ "nextest" , "run" , "--package" , "my-crate" ] ,
950+ }
951+ } ) ;
952+
953+ let serialized = serde_json:: to_value ( & runnable) . expect ( "serialized runnable" ) ;
954+ assert_eq ! ( serialized, expected) ;
955+
956+ // Every shell runnable is a structurally valid cargo runnable if the `kind` tag isn't
957+ // used. This test ensures that the `kind` tag is used.
958+ let deserialized: Runnable =
959+ serde_json:: from_value ( expected) . expect ( "shell runnable should deserialize" ) ;
960+ let RunnableArgs :: Shell ( shell) = & deserialized. args else {
961+ panic ! ( "expected Shell variant, got {:?}" , deserialized. args) ;
962+ } ;
963+ assert_eq ! ( shell. program, "cargo" ) ;
964+ assert_eq ! ( shell. args, vec![ "nextest" , "run" , "--package" , "my-crate" ] ) ;
965+ }
966+ }
0 commit comments