@@ -25,7 +25,8 @@ use uv_normalize::{ExtraName, GroupName, PackageName};
25
25
use uv_pep440:: { Version , VersionSpecifiers } ;
26
26
use uv_pep508:: MarkerTree ;
27
27
use uv_pypi_types:: {
28
- ConflictingGroupList , RequirementSource , SupportedEnvironments , VerbatimParsedUrl ,
28
+ ConflictingGroup , ConflictingGroupList , ConflictingGroups , RequirementSource ,
29
+ SupportedEnvironments , VerbatimParsedUrl ,
29
30
} ;
30
31
31
32
#[ derive( Error , Debug ) ]
@@ -483,6 +484,88 @@ pub struct ToolUv {
483
484
pub conflicting_groups : Option < ConflictingGroupList > ,
484
485
}
485
486
487
+ #[ derive( Debug , Default , Clone , Eq , PartialEq , serde:: Deserialize , serde:: Serialize ) ]
488
+ #[ cfg_attr( feature = "schemars" , derive( schemars:: JsonSchema ) ) ]
489
+ pub struct ToolUvConflictingList ( Vec < ToolUvConflictingSet > ) ;
490
+
491
+ impl ToolUvConflictingList {
492
+ pub fn to_conflicting ( & self , package : & PackageName ) -> ConflictingGroupList {
493
+ let mut conflicting = ConflictingGroupList :: empty ( ) ;
494
+ for tool_uv_set in & self . 0 {
495
+ let mut set = vec ! [ ] ;
496
+ for item in & tool_uv_set. 0 {
497
+ set. push ( ConflictingGroup :: from ( (
498
+ package. clone ( ) ,
499
+ item. extra . clone ( ) ,
500
+ ) ) ) ;
501
+ }
502
+ // OK because we guarantee that `ToolUvConflictingList` is
503
+ // valid and there aren't any new errors that can occur
504
+ // here.
505
+ let set = ConflictingGroups :: try_from ( set) . unwrap ( ) ;
506
+ conflicting. push ( set) ;
507
+ }
508
+ conflicting
509
+ }
510
+ }
511
+
512
+ #[ derive( Debug , Default , Clone , Eq , PartialEq , serde:: Serialize ) ]
513
+ #[ cfg_attr( feature = "schemars" , derive( schemars:: JsonSchema ) ) ]
514
+ pub struct ToolUvConflictingSet ( Vec < ToolUvConflictingItem > ) ;
515
+
516
+ #[ derive(
517
+ Debug ,
518
+ Default ,
519
+ Clone ,
520
+ Eq ,
521
+ Hash ,
522
+ PartialEq ,
523
+ PartialOrd ,
524
+ Ord ,
525
+ serde:: Deserialize ,
526
+ serde:: Serialize ,
527
+ ) ]
528
+ #[ cfg_attr( feature = "schemars" , derive( schemars:: JsonSchema ) ) ]
529
+ pub struct ToolUvConflictingItem {
530
+ extra : ExtraName ,
531
+ }
532
+
533
+ impl < ' de > serde:: Deserialize < ' de > for ToolUvConflictingSet {
534
+ fn deserialize < D > ( deserializer : D ) -> Result < ToolUvConflictingSet , D :: Error >
535
+ where
536
+ D : serde:: Deserializer < ' de > ,
537
+ {
538
+ let items = Vec :: < ToolUvConflictingItem > :: deserialize ( deserializer) ?;
539
+ Self :: try_from ( items) . map_err ( serde:: de:: Error :: custom)
540
+ }
541
+ }
542
+
543
+ impl TryFrom < Vec < ToolUvConflictingItem > > for ToolUvConflictingSet {
544
+ type Error = ToolUvConflictingError ;
545
+
546
+ fn try_from (
547
+ items : Vec < ToolUvConflictingItem > ,
548
+ ) -> Result < ToolUvConflictingSet , ToolUvConflictingError > {
549
+ match items. len ( ) {
550
+ 0 => return Err ( ToolUvConflictingError :: ZeroGroups ) ,
551
+ 1 => return Err ( ToolUvConflictingError :: OneGroup ) ,
552
+ _ => { }
553
+ }
554
+ Ok ( ToolUvConflictingSet ( items) )
555
+ }
556
+ }
557
+
558
+ /// An error that occurs when the given conflicting groups are invalid somehow.
559
+ #[ derive( Debug , thiserror:: Error ) ]
560
+ pub enum ToolUvConflictingError {
561
+ /// An error for when there are zero conflicting groups.
562
+ #[ error( "Each set of conflicts must have at least two entries, but found none" ) ]
563
+ ZeroGroups ,
564
+ /// An error for when there is one conflicting group.
565
+ #[ error( "Each set of conflicts must have at least two entries, but found only one" ) ]
566
+ OneGroup ,
567
+ }
568
+
486
569
#[ derive( Default , Debug , Clone , PartialEq , Eq ) ]
487
570
#[ cfg_attr( test, derive( Serialize ) ) ]
488
571
#[ cfg_attr( feature = "schemars" , derive( schemars:: JsonSchema ) ) ]
0 commit comments