1
1
use derive_more:: { Deref , From } ;
2
- use git_url_parse:: { GitUrl , Scheme as GitUrlScheme } ;
2
+ use git_url_parse:: GitUrl ;
3
3
use monostate:: MustBe ;
4
4
use serde:: de:: { Error , MapAccess , SeqAccess , Visitor } ;
5
5
use serde:: ser:: { SerializeMap , Serializer } ;
@@ -627,25 +627,23 @@ impl From<String> for ComposerUrlOrPathUrl {
627
627
}
628
628
}
629
629
630
- // for some sources (and their mirrors) such as 'git', three kinds of URLs are allowed:
630
+ // For some sources (and their mirrors) such as 'git', three kinds of URLs are allowed:
631
631
// 1) URL style (e.g. https://github.com/foo/bar)
632
632
// 2) SSH style (e.g. [email protected] :foo/bar.git)
633
633
// 3) local filesystem path
634
- // so the URL type has to permit all of these
634
+ // Style 2 is normalized into style 1 during parsing
635
635
#[ derive( Clone , Debug , Deserialize , Serialize ) ]
636
636
#[ serde( try_from = "String" ) ]
637
637
#[ serde( into = "String" ) ]
638
638
pub enum ComposerUrlOrSshOrPathUrl {
639
639
Url ( Url ) ,
640
- GitUrl ( GitUrl ) ,
641
640
Path ( PathBuf ) ,
642
641
}
643
642
644
643
impl From < ComposerUrlOrSshOrPathUrl > for String {
645
644
fn from ( val : ComposerUrlOrSshOrPathUrl ) -> Self {
646
645
match val {
647
646
ComposerUrlOrSshOrPathUrl :: Url ( v) => v. into ( ) ,
648
- ComposerUrlOrSshOrPathUrl :: GitUrl ( v) => v. to_string ( ) ,
649
647
ComposerUrlOrSshOrPathUrl :: Path ( v) => format ! ( "{}" , v. display( ) ) ,
650
648
}
651
649
}
@@ -657,20 +655,22 @@ impl TryFrom<String> for ComposerUrlOrSshOrPathUrl {
657
655
// try and parse as a regular Url first
658
656
// reason is that Url handles e.g. 'svn+ssh://...' correctly
659
657
// GitUrl really is only for the '[email protected] :foo/bar.git' cases
660
- match Url :: parse ( & value) {
661
- Ok ( url) => Ok ( Self :: Url ( url) ) ,
662
- Err ( _) => match GitUrl :: parse ( & value) {
663
- Ok ( url) => {
664
- match url. scheme {
665
- // GitUrl will parse "local" URLs like "./foo", "foo/bar", "../test"
666
- // in that case we want to return a Path variant instead
667
- GitUrlScheme :: File => Ok ( Self :: Path ( PathBuf :: from ( & value) ) ) ,
668
- _ => Ok ( Self :: GitUrl ( url) ) ,
658
+ // (and even then, we convert back to a regular Url)
659
+ Url :: parse ( & value)
660
+ . map ( Self :: Url )
661
+ . or_else ( |_| {
662
+ GitUrl :: parse ( & value) . and_then ( |git_url| {
663
+ match & git_url. scheme ( ) {
664
+ // it's a file, but url::Url did not parse it as such, since it was relative
665
+ // git-url-parse, however, accepts those
666
+ // in that case, we return a PathBuf instead of a Url
667
+ Some ( "file" ) => Ok ( Self :: Path ( PathBuf :: from ( & value) ) ) ,
668
+ // it's an SSH style URL, "normalize" it to url::Url
669
+ _ => Ok ( Self :: Url ( git_url. try_into ( ) ?) ) ,
669
670
}
670
- }
671
- Err ( e) => Err ( format ! ( "Invalid GitUrl {value}: {e}" ) ) ,
672
- } ,
673
- }
671
+ } )
672
+ } )
673
+ . map_err ( |e| format ! ( "Invalid GitUrl {value}: {e}" ) )
674
674
}
675
675
}
676
676
0 commit comments