@@ -55,8 +55,9 @@ use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
55
55
use rustc_hash:: FxHashMap ;
56
56
use serde:: { de, Deserialize } ;
57
57
use span:: Edition ;
58
+ use std:: path:: PathBuf ;
58
59
59
- use crate :: cfg_flag:: CfgFlag ;
60
+ use crate :: { cfg_flag:: CfgFlag , TargetKind } ;
60
61
61
62
/// Roots and crates that compose this Rust project.
62
63
#[ derive( Clone , Debug , Eq , PartialEq ) ]
@@ -87,6 +88,21 @@ pub struct Crate {
87
88
pub ( crate ) exclude : Vec < AbsPathBuf > ,
88
89
pub ( crate ) is_proc_macro : bool ,
89
90
pub ( crate ) repository : Option < String > ,
91
+ pub build_info : Option < BuildInfo > ,
92
+ }
93
+
94
+ /// Additional metadata about a crate, used to configure runnables.
95
+ #[ derive( Clone , Debug , Eq , PartialEq ) ]
96
+ pub struct BuildInfo {
97
+ /// The name associated with this crate, according to the custom
98
+ /// build system being used.
99
+ pub label : String ,
100
+ /// What kind of target is this crate? For example, we don't want
101
+ /// to offer a 'run' button for library crates.
102
+ pub target_kind : TargetKind ,
103
+ /// Configuration for shell commands, such as CLI invocations for
104
+ /// a check build or a test run.
105
+ pub shell_runnables : Vec < ShellRunnableArgs > ,
90
106
}
91
107
92
108
impl ProjectJson {
@@ -121,6 +137,15 @@ impl ProjectJson {
121
137
None => ( vec ! [ root_module. parent( ) . unwrap( ) . to_path_buf( ) ] , Vec :: new ( ) ) ,
122
138
} ;
123
139
140
+ let build_info = match crate_data. build_info {
141
+ Some ( build_info) => Some ( BuildInfo {
142
+ label : build_info. label ,
143
+ target_kind : build_info. target_kind . into ( ) ,
144
+ shell_runnables : build_info. shell_runnables ,
145
+ } ) ,
146
+ None => None ,
147
+ } ;
148
+
124
149
Crate {
125
150
display_name : crate_data
126
151
. display_name
@@ -149,6 +174,7 @@ impl ProjectJson {
149
174
exclude,
150
175
is_proc_macro : crate_data. is_proc_macro ,
151
176
repository : crate_data. repository ,
177
+ build_info,
152
178
}
153
179
} )
154
180
. collect ( ) ,
@@ -172,6 +198,14 @@ impl ProjectJson {
172
198
pub fn path ( & self ) -> & AbsPath {
173
199
& self . project_root
174
200
}
201
+
202
+ pub fn crate_by_root ( & self , root : & AbsPath ) -> Option < Crate > {
203
+ self . crates
204
+ . iter ( )
205
+ . filter ( |krate| krate. is_workspace_member )
206
+ . find ( |krate| krate. root_module == root)
207
+ . cloned ( )
208
+ }
175
209
}
176
210
177
211
#[ derive( Deserialize , Debug , Clone ) ]
@@ -201,6 +235,8 @@ struct CrateData {
201
235
is_proc_macro : bool ,
202
236
#[ serde( default ) ]
203
237
repository : Option < String > ,
238
+ #[ serde( default ) ]
239
+ build_info : Option < BuildInfoData > ,
204
240
}
205
241
206
242
#[ derive( Deserialize , Debug , Clone ) ]
@@ -216,6 +252,48 @@ enum EditionData {
216
252
Edition2024 ,
217
253
}
218
254
255
+ #[ derive( Deserialize , Debug , Clone ) ]
256
+ pub struct BuildInfoData {
257
+ label : String ,
258
+ target_kind : TargetKindData ,
259
+ shell_runnables : Vec < ShellRunnableArgs > ,
260
+ }
261
+
262
+ #[ derive( Debug , Clone , PartialEq , Eq , serde:: Deserialize ) ]
263
+ #[ serde( rename_all = "camelCase" ) ]
264
+ pub struct ShellRunnableArgs {
265
+ pub program : String ,
266
+ pub args : Vec < String > ,
267
+ pub cwd : PathBuf ,
268
+ pub kind : ShellRunnableKind ,
269
+ }
270
+
271
+ #[ derive( Debug , Clone , PartialEq , Eq , serde:: Deserialize ) ]
272
+ #[ serde( rename_all = "camelCase" ) ]
273
+ pub enum ShellRunnableKind {
274
+ Check ,
275
+ Run ,
276
+ }
277
+
278
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , serde:: Deserialize ) ]
279
+ #[ serde( rename_all = "camelCase" ) ]
280
+ pub enum TargetKindData {
281
+ Bin ,
282
+ /// Any kind of Cargo lib crate-type (dylib, rlib, proc-macro, ...).
283
+ Lib ,
284
+ Test ,
285
+ }
286
+
287
+ impl From < TargetKindData > for TargetKind {
288
+ fn from ( value : TargetKindData ) -> Self {
289
+ match value {
290
+ TargetKindData :: Bin => TargetKind :: Bin ,
291
+ TargetKindData :: Lib => TargetKind :: Lib { is_proc_macro : false } ,
292
+ TargetKindData :: Test => TargetKind :: Test ,
293
+ }
294
+ }
295
+ }
296
+
219
297
impl From < EditionData > for Edition {
220
298
fn from ( data : EditionData ) -> Self {
221
299
match data {
0 commit comments