1
1
use std:: collections:: BTreeMap ;
2
+ use std:: fmt:: { Display , Formatter } ;
2
3
use std:: path:: { Path , PathBuf } ;
3
4
4
5
use indexmap:: IndexSet ;
@@ -74,6 +75,7 @@ impl Dependency {
74
75
Some ( Source :: Git ( git) ) => {
75
76
git. version = None ;
76
77
}
78
+ Some ( Source :: Workspace ( _workspace) ) => { }
77
79
None => { }
78
80
}
79
81
self
@@ -161,6 +163,7 @@ impl Dependency {
161
163
Source :: Registry ( src) => Some ( src. version . as_str ( ) ) ,
162
164
Source :: Path ( src) => src. version . as_deref ( ) ,
163
165
Source :: Git ( src) => src. version . as_deref ( ) ,
166
+ Source :: Workspace ( _) => None ,
164
167
}
165
168
}
166
169
@@ -185,29 +188,47 @@ impl Dependency {
185
188
}
186
189
187
190
/// Get the SourceID for this dependency
188
- pub fn source_id ( & self , config : & Config ) -> CargoResult < SourceId > {
191
+ pub fn source_id ( & self , config : & Config ) -> CargoResult < MaybeWorkspace < SourceId > > {
189
192
match & self . source . as_ref ( ) {
190
193
Some ( Source :: Registry ( _) ) | None => {
191
194
if let Some ( r) = self . registry ( ) {
192
195
let source_id = SourceId :: alt_registry ( config, r) ?;
193
- Ok ( source_id)
196
+ Ok ( MaybeWorkspace :: Other ( source_id) )
194
197
} else {
195
198
let source_id = SourceId :: crates_io ( config) ?;
196
- Ok ( source_id)
199
+ Ok ( MaybeWorkspace :: Other ( source_id) )
197
200
}
198
201
}
199
- Some ( Source :: Path ( source) ) => source. source_id ( ) ,
200
- Some ( Source :: Git ( source) ) => source. source_id ( ) ,
202
+ Some ( Source :: Path ( source) ) => Ok ( MaybeWorkspace :: Other ( source. source_id ( ) ?) ) ,
203
+ Some ( Source :: Git ( source) ) => Ok ( MaybeWorkspace :: Other ( source. source_id ( ) ?) ) ,
204
+ Some ( Source :: Workspace ( workspace) ) => Ok ( MaybeWorkspace :: Workspace ( workspace. clone ( ) ) ) ,
201
205
}
202
206
}
203
207
204
208
/// Query to find this dependency
205
- pub fn query ( & self , config : & Config ) -> CargoResult < crate :: core:: dependency:: Dependency > {
209
+ pub fn query (
210
+ & self ,
211
+ config : & Config ,
212
+ ) -> CargoResult < MaybeWorkspace < crate :: core:: dependency:: Dependency > > {
206
213
let source_id = self . source_id ( config) ?;
207
- crate :: core:: dependency:: Dependency :: parse ( self . name . as_str ( ) , self . version ( ) , source_id)
214
+ match source_id {
215
+ MaybeWorkspace :: Workspace ( workspace) => Ok ( MaybeWorkspace :: Workspace ( workspace) ) ,
216
+ MaybeWorkspace :: Other ( source_id) => Ok ( MaybeWorkspace :: Other (
217
+ crate :: core:: dependency:: Dependency :: parse (
218
+ self . name . as_str ( ) ,
219
+ self . version ( ) ,
220
+ source_id,
221
+ ) ?,
222
+ ) ) ,
223
+ }
208
224
}
209
225
}
210
226
227
+ pub enum MaybeWorkspace < T > {
228
+ Workspace ( WorkspaceSource ) ,
229
+ Other ( T ) ,
230
+ }
231
+
211
232
impl Dependency {
212
233
/// Create a dependency from a TOML table entry
213
234
pub fn from_toml ( crate_root : & Path , key : & str , item : & toml_edit:: Item ) -> CargoResult < Self > {
@@ -271,6 +292,15 @@ impl Dependency {
271
292
invalid_type ( key, "version" , version. type_name ( ) , "string" )
272
293
} ) ?) ;
273
294
src. into ( )
295
+ } else if let Some ( workspace) = table. get ( "workspace" ) {
296
+ let workspace_bool = workspace. as_bool ( ) . ok_or_else ( || {
297
+ invalid_type ( key, "workspace" , workspace. type_name ( ) , "bool" )
298
+ } ) ?;
299
+ if !workspace_bool {
300
+ anyhow:: bail!( "`{key}.workspace = false` is unsupported" )
301
+ }
302
+ let src = WorkspaceSource :: new ( ) ;
303
+ src. into ( )
274
304
} else {
275
305
anyhow:: bail!( "Unrecognized dependency source for `{key}`" ) ;
276
306
} ;
@@ -367,6 +397,12 @@ impl Dependency {
367
397
None ,
368
398
None ,
369
399
) => toml_edit:: value ( v) ,
400
+ ( false , None , true , Some ( Source :: Workspace ( WorkspaceSource { } ) ) , None , None ) => {
401
+ let mut table = toml_edit:: InlineTable :: default ( ) ;
402
+ table. set_dotted ( true ) ;
403
+ table. insert ( "workspace" , true . into ( ) ) ;
404
+ toml_edit:: value ( toml_edit:: Value :: InlineTable ( table) )
405
+ }
370
406
// Other cases are represented as an inline table
371
407
( _, _, _, _, _, _) => {
372
408
let mut table = toml_edit:: InlineTable :: default ( ) ;
@@ -397,6 +433,9 @@ impl Dependency {
397
433
table. insert ( "version" , r. into ( ) ) ;
398
434
}
399
435
}
436
+ Some ( Source :: Workspace ( _) ) => {
437
+ table. insert ( "workspace" , true . into ( ) ) ;
438
+ }
400
439
None => { }
401
440
}
402
441
if table. contains_key ( "version" ) {
@@ -436,7 +475,7 @@ impl Dependency {
436
475
Some ( Source :: Registry ( src) ) => {
437
476
table. insert ( "version" , toml_edit:: value ( src. version . as_str ( ) ) ) ;
438
477
439
- for key in [ "path" , "git" , "branch" , "tag" , "rev" ] {
478
+ for key in [ "path" , "git" , "branch" , "tag" , "rev" , "workspace" ] {
440
479
table. remove ( key) ;
441
480
}
442
481
}
@@ -449,7 +488,7 @@ impl Dependency {
449
488
table. remove ( "version" ) ;
450
489
}
451
490
452
- for key in [ "git" , "branch" , "tag" , "rev" ] {
491
+ for key in [ "git" , "branch" , "tag" , "rev" , "workspace" ] {
453
492
table. remove ( key) ;
454
493
}
455
494
}
@@ -476,7 +515,23 @@ impl Dependency {
476
515
table. remove ( "version" ) ;
477
516
}
478
517
479
- for key in [ "path" ] {
518
+ for key in [ "path" , "workspace" ] {
519
+ table. remove ( key) ;
520
+ }
521
+ }
522
+ Some ( Source :: Workspace ( _) ) => {
523
+ table. set_dotted ( true ) ;
524
+ for key in [
525
+ "version" ,
526
+ "registry" ,
527
+ "registry-index" ,
528
+ "path" ,
529
+ "git" ,
530
+ "branch" ,
531
+ "tag" ,
532
+ "rev" ,
533
+ "package" ,
534
+ ] {
480
535
table. remove ( key) ;
481
536
}
482
537
}
@@ -516,12 +571,14 @@ impl Dependency {
516
571
. unwrap_or_default ( ) ;
517
572
features. extend ( new_features. iter ( ) . map ( |s| s. as_str ( ) ) ) ;
518
573
let features = toml_edit:: value ( features. into_iter ( ) . collect :: < toml_edit:: Value > ( ) ) ;
574
+ table. set_dotted ( false ) ;
519
575
table. insert ( "features" , features) ;
520
576
} else {
521
577
table. remove ( "features" ) ;
522
578
}
523
579
match self . optional {
524
580
Some ( v) => {
581
+ table. set_dotted ( false ) ;
525
582
table. insert ( "optional" , toml_edit:: value ( v) ) ;
526
583
}
527
584
None => {
@@ -596,6 +653,8 @@ pub enum Source {
596
653
Path ( PathSource ) ,
597
654
/// Dependency from a git repo
598
655
Git ( GitSource ) ,
656
+ /// Dependency from a workspace
657
+ Workspace ( WorkspaceSource ) ,
599
658
}
600
659
601
660
impl Source {
@@ -624,6 +683,15 @@ impl Source {
624
683
_ => None ,
625
684
}
626
685
}
686
+
687
+ /// Access the workspace source, if present
688
+ #[ allow( dead_code) ]
689
+ pub fn as_workspace ( & self ) -> Option < & WorkspaceSource > {
690
+ match self {
691
+ Self :: Workspace ( src) => Some ( src) ,
692
+ _ => None ,
693
+ }
694
+ }
627
695
}
628
696
629
697
impl std:: fmt:: Display for Source {
@@ -632,6 +700,7 @@ impl std::fmt::Display for Source {
632
700
Self :: Registry ( src) => src. fmt ( f) ,
633
701
Self :: Path ( src) => src. fmt ( f) ,
634
702
Self :: Git ( src) => src. fmt ( f) ,
703
+ Self :: Workspace ( src) => src. fmt ( f) ,
635
704
}
636
705
}
637
706
}
@@ -660,6 +729,12 @@ impl From<GitSource> for Source {
660
729
}
661
730
}
662
731
732
+ impl From < WorkspaceSource > for Source {
733
+ fn from ( inner : WorkspaceSource ) -> Self {
734
+ Self :: Workspace ( inner)
735
+ }
736
+ }
737
+
663
738
/// Dependency from a registry
664
739
#[ derive( Debug , Hash , PartialEq , Eq , Clone ) ]
665
740
#[ non_exhaustive]
@@ -822,6 +897,23 @@ impl std::fmt::Display for GitSource {
822
897
}
823
898
}
824
899
900
+ /// Dependency from a workspace
901
+ #[ derive( Debug , Hash , PartialEq , Eq , Clone ) ]
902
+ #[ non_exhaustive]
903
+ pub struct WorkspaceSource ;
904
+
905
+ impl WorkspaceSource {
906
+ pub fn new ( ) -> Self {
907
+ Self
908
+ }
909
+ }
910
+
911
+ impl Display for WorkspaceSource {
912
+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
913
+ "workspace" . fmt ( f)
914
+ }
915
+ }
916
+
825
917
#[ cfg( test) ]
826
918
mod tests {
827
919
use std:: path:: Path ;
0 commit comments