@@ -15,6 +15,26 @@ use std::ptr;
15
15
use std:: sync:: Mutex ;
16
16
use url:: Url ;
17
17
18
+ // Encode a name or value for a query string
19
+ //
20
+ // https://url.spec.whatwg.org/#urlencoded-serializing
21
+ //
22
+ // The result of running percent-encode after encoding with encoding,
23
+ // tuple’s name, the application/x-www-form-urlencoded percent-encode
24
+ // set, and true
25
+ //
26
+ // We can't use percent_encoding directly because spaces are handled in
27
+ // a peculiar way.
28
+ fn write_form_urlencoded_component (
29
+ fmt : & mut Formatter < ' _ > ,
30
+ component : & str ,
31
+ ) -> Result < ( ) , fmt:: Error > {
32
+ for s in form_urlencoded:: byte_serialize ( component. as_bytes ( ) ) {
33
+ fmt. write_str ( s) ?;
34
+ }
35
+ Ok ( ( ) )
36
+ }
37
+
18
38
lazy_static:: lazy_static! {
19
39
static ref SOURCE_ID_CACHE : Mutex <HashSet <& ' static SourceIdInner >> = Default :: default ( ) ;
20
40
}
@@ -714,9 +734,18 @@ pub struct PrettyRef<'a> {
714
734
impl < ' a > fmt:: Display for PrettyRef < ' a > {
715
735
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
716
736
match * self . inner {
717
- GitReference :: Branch ( ref b) => write ! ( f, "branch={}" , b) ,
718
- GitReference :: Tag ( ref s) => write ! ( f, "tag={}" , s) ,
719
- GitReference :: Rev ( ref s) => write ! ( f, "rev={}" , s) ,
737
+ GitReference :: Branch ( ref b) => {
738
+ f. write_str ( "branch=" ) ?;
739
+ write_form_urlencoded_component ( f, b)
740
+ }
741
+ GitReference :: Tag ( ref s) => {
742
+ f. write_str ( "tag=" ) ?;
743
+ write_form_urlencoded_component ( f, s)
744
+ }
745
+ GitReference :: Rev ( ref s) => {
746
+ f. write_str ( "rev=" ) ?;
747
+ write_form_urlencoded_component ( f, s)
748
+ }
720
749
GitReference :: DefaultBranch => unreachable ! ( ) ,
721
750
}
722
751
}
@@ -751,7 +780,16 @@ mod tests {
751
780
let ser1 = format ! ( "{}" , s1. as_url( ) ) ;
752
781
let s2 = SourceId :: from_url ( & ser1) . expect ( "Failed to deserialize" ) ;
753
782
let ser2 = format ! ( "{}" , s2. as_url( ) ) ;
783
+ // Serializing twice should yield the same result
754
784
assert_eq ! ( ser1, ser2, "Serialized forms don't match" ) ;
785
+ // SourceId serializing the same should have the same semantics
786
+ // This used to not be the case (# was ambiguous)
755
787
assert_eq ! ( s1, s2, "SourceId doesn't round-trip" ) ;
788
+ // Freeze the format to match an x-www-form-urlencoded query string
789
+ // https://url.spec.whatwg.org/#application/x-www-form-urlencoded
790
+ assert_eq ! (
791
+ ser1,
792
+ "git+https://host/path?branch=*-._%2B20%2530+Z%2Fz%23foo%3Dbar%26zap%5B%5D%3Fto%5C%28%29%27%22"
793
+ ) ;
756
794
}
757
795
}
0 commit comments