@@ -196,13 +196,13 @@ impl EncodableResolve {
196
196
let enc_id = EncodablePackageId {
197
197
name : pkg. name . clone ( ) ,
198
198
version : Some ( pkg. version . clone ( ) ) ,
199
- source : pkg. source ,
199
+ source : pkg. source . clone ( ) ,
200
200
} ;
201
201
202
202
if !all_pkgs. insert ( enc_id. clone ( ) ) {
203
203
anyhow:: bail!( "package `{}` is specified twice in the lockfile" , pkg. name) ;
204
204
}
205
- let id = match pkg. source . as_ref ( ) . or_else ( || path_deps. get ( & pkg. name ) ) {
205
+ let id = match pkg. source . as_deref ( ) . or_else ( || path_deps. get ( & pkg. name ) ) {
206
206
// We failed to find a local package in the workspace.
207
207
// It must have been removed and should be ignored.
208
208
None => {
@@ -366,7 +366,7 @@ impl EncodableResolve {
366
366
367
367
let mut unused_patches = Vec :: new ( ) ;
368
368
for pkg in self . patch . unused {
369
- let id = match pkg. source . as_ref ( ) . or_else ( || path_deps. get ( & pkg. name ) ) {
369
+ let id = match pkg. source . as_deref ( ) . or_else ( || path_deps. get ( & pkg. name ) ) {
370
370
Some ( & src) => PackageId :: new ( & pkg. name , & pkg. version , src) ?,
371
371
None => continue ,
372
372
} ;
@@ -488,17 +488,95 @@ impl Patch {
488
488
pub struct EncodableDependency {
489
489
name : String ,
490
490
version : String ,
491
- source : Option < SourceId > ,
491
+ source : Option < EncodableSourceId > ,
492
492
checksum : Option < String > ,
493
493
dependencies : Option < Vec < EncodablePackageId > > ,
494
494
replace : Option < EncodablePackageId > ,
495
495
}
496
496
497
+ /// Pretty much equivalent to [`SourceId`] with a different serialization method.
498
+ ///
499
+ /// The serialization for `SourceId` doesn't do URL encode for parameters.
500
+ /// In contrast, this type is aware of that whenever [`ResolveVersion`] allows
501
+ /// us to do so (v4 or later).
502
+ ///
503
+ /// [`EncodableResolve`] turns into a `
504
+ #[ derive( Deserialize , Debug , PartialOrd , Ord , Clone ) ]
505
+ #[ serde( transparent) ]
506
+ pub struct EncodableSourceId {
507
+ inner : SourceId ,
508
+ /// We don't care about the deserialization of this, as the `url` crate
509
+ /// will always decode as the URL was encoded. Only when a [`Resolve`]
510
+ /// turns into a [`EncodableResolve`] will it set the value accordingly
511
+ /// via [`encodable_source_id`].
512
+ #[ serde( skip) ]
513
+ encoded : bool ,
514
+ }
515
+
516
+ impl EncodableSourceId {
517
+ /// Creates a `EncodableSourceId` that always encodes URL params.
518
+ fn new ( inner : SourceId ) -> Self {
519
+ Self {
520
+ inner,
521
+ encoded : true ,
522
+ }
523
+ }
524
+
525
+ /// Creates a `EncodableSourceId` that doesn't encode URL params. This is
526
+ /// for backward compatibility for order lockfile version.
527
+ fn without_url_encoded ( inner : SourceId ) -> Self {
528
+ Self {
529
+ inner,
530
+ encoded : false ,
531
+ }
532
+ }
533
+
534
+ /// Encodes the inner [`SourceId`] as a URL.
535
+ fn as_url ( & self ) -> impl fmt:: Display + ' _ {
536
+ if self . encoded {
537
+ self . inner . as_encoded_url ( )
538
+ } else {
539
+ self . inner . as_url ( )
540
+ }
541
+ }
542
+ }
543
+
544
+ impl std:: ops:: Deref for EncodableSourceId {
545
+ type Target = SourceId ;
546
+
547
+ fn deref ( & self ) -> & Self :: Target {
548
+ & self . inner
549
+ }
550
+ }
551
+
552
+ impl ser:: Serialize for EncodableSourceId {
553
+ fn serialize < S > ( & self , s : S ) -> Result < S :: Ok , S :: Error >
554
+ where
555
+ S : ser:: Serializer ,
556
+ {
557
+ s. collect_str ( & self . as_url ( ) )
558
+ }
559
+ }
560
+
561
+ impl std:: hash:: Hash for EncodableSourceId {
562
+ fn hash < H : std:: hash:: Hasher > ( & self , state : & mut H ) {
563
+ self . inner . hash ( state)
564
+ }
565
+ }
566
+
567
+ impl std:: cmp:: PartialEq for EncodableSourceId {
568
+ fn eq ( & self , other : & Self ) -> bool {
569
+ self . inner == other. inner
570
+ }
571
+ }
572
+
573
+ impl std:: cmp:: Eq for EncodableSourceId { }
574
+
497
575
#[ derive( Debug , PartialOrd , Ord , PartialEq , Eq , Hash , Clone ) ]
498
576
pub struct EncodablePackageId {
499
577
name : String ,
500
578
version : Option < String > ,
501
- source : Option < SourceId > ,
579
+ source : Option < EncodableSourceId > ,
502
580
}
503
581
504
582
impl fmt:: Display for EncodablePackageId {
@@ -535,7 +613,8 @@ impl FromStr for EncodablePackageId {
535
613
Ok ( EncodablePackageId {
536
614
name : name. to_string ( ) ,
537
615
version : version. map ( |v| v. to_string ( ) ) ,
538
- source : source_id,
616
+ // Default to url encoded.
617
+ source : source_id. map ( EncodableSourceId :: new) ,
539
618
} )
540
619
}
541
620
}
@@ -603,7 +682,7 @@ impl ser::Serialize for Resolve {
603
682
. map ( |id| EncodableDependency {
604
683
name : id. name ( ) . to_string ( ) ,
605
684
version : id. version ( ) . to_string ( ) ,
606
- source : encode_source ( id. source_id ( ) ) ,
685
+ source : encodable_source_id ( id. source_id ( ) , self . version ( ) ) ,
607
686
dependencies : None ,
608
687
replace : None ,
609
688
checksum : if self . version ( ) >= ResolveVersion :: V2 {
@@ -676,7 +755,7 @@ fn encodable_resolve_node(
676
755
EncodableDependency {
677
756
name : id. name ( ) . to_string ( ) ,
678
757
version : id. version ( ) . to_string ( ) ,
679
- source : encode_source ( id. source_id ( ) ) ,
758
+ source : encodable_source_id ( id. source_id ( ) , resolve . version ( ) ) ,
680
759
dependencies : deps,
681
760
replace,
682
761
checksum : if resolve. version ( ) >= ResolveVersion :: V2 {
@@ -702,7 +781,7 @@ pub fn encodable_package_id(
702
781
}
703
782
}
704
783
}
705
- let mut source = encode_source ( id_to_encode) . map ( |s| s . with_precise ( None ) ) ;
784
+ let mut source = encodable_source_id ( id_to_encode. with_precise ( None ) , resolve_version ) ;
706
785
if let Some ( counts) = & state. counts {
707
786
let version_counts = & counts[ & id. name ( ) ] ;
708
787
if version_counts[ & id. version ( ) ] == 1 {
@@ -719,10 +798,13 @@ pub fn encodable_package_id(
719
798
}
720
799
}
721
800
722
- fn encode_source ( id : SourceId ) -> Option < SourceId > {
801
+ fn encodable_source_id ( id : SourceId , version : ResolveVersion ) -> Option < EncodableSourceId > {
723
802
if id. is_path ( ) {
724
803
None
725
804
} else {
726
- Some ( id)
805
+ Some ( match version {
806
+ ResolveVersion :: V4 => EncodableSourceId :: new ( id) ,
807
+ _ => EncodableSourceId :: without_url_encoded ( id) ,
808
+ } )
727
809
}
728
810
}
0 commit comments