@@ -477,7 +477,7 @@ impl Url {
477477 assert_eq ! ( host_str, h. to_string( ) )
478478 }
479479 HostInternal :: Domain => {
480- if SchemeType :: from ( self . scheme ( ) ) . is_special ( ) {
480+ if self . is_special ( ) {
481481 assert ! ( !host_str. is_empty( ) )
482482 }
483483 }
@@ -1635,7 +1635,7 @@ impl Url {
16351635 }
16361636
16371637 if let Some ( host) = host {
1638- if host == "" && SchemeType :: from ( self . scheme ( ) ) . is_special ( ) {
1638+ if host == "" && self . is_special ( ) {
16391639 return Err ( ParseError :: EmptyHost ) ;
16401640 }
16411641 let mut host_substr = host;
@@ -1653,14 +1653,13 @@ impl Url {
16531653 None => { }
16541654 }
16551655 }
1656- if SchemeType :: from ( self . scheme ( ) ) . is_special ( ) {
1656+ if self . is_special ( ) {
16571657 self . set_host_internal ( Host :: parse ( host_substr) ?, None ) ;
16581658 } else {
16591659 self . set_host_internal ( Host :: parse_opaque ( host_substr) ?, None ) ;
16601660 }
16611661 } else if self . has_host ( ) {
1662- let scheme_type = SchemeType :: from ( self . scheme ( ) ) ;
1663- if scheme_type. is_special ( ) {
1662+ if self . is_special ( ) {
16641663 return Err ( ParseError :: EmptyHost ) ;
16651664 } else {
16661665 if self . serialization . len ( ) == self . path_start as usize {
@@ -2103,6 +2102,68 @@ impl Url {
21032102 Ok ( ( ) )
21042103 }
21052104
2105+ /// Return whether the URL is special.
2106+ ///
2107+ /// A URL is special if its scheme is one of the following:
2108+ ///
2109+ /// "http" | "https" | "ws" | "wss" | "ftp" | "gopher" | "file"
2110+ ///
2111+ /// # Examples
2112+ ///
2113+ /// ```
2114+ /// use url::Url;
2115+ /// # use url::ParseError;
2116+ ///
2117+ /// # fn run() -> Result<(), ParseError> {
2118+ /// let url = Url::parse("ftp://rms@example.com")?;
2119+ /// assert!(url.is_special());
2120+ ///
2121+ /// let url = Url::parse("file://foo.bar")?;
2122+ /// assert!(url.is_special());
2123+ ///
2124+ /// let url = Url::parse("unix:/run/foo.socket")?;
2125+ /// assert!(!url.is_special());
2126+ ///
2127+ /// let url = Url::parse("data:text/plain,Stuff")?;
2128+ /// assert!(!url.is_special());
2129+ /// # Ok(())
2130+ /// # }
2131+ /// # run().unwrap();
2132+ /// ```
2133+ pub fn is_special ( & self ) -> bool {
2134+ SchemeType :: from ( self . scheme ( ) ) . is_special ( )
2135+ }
2136+
2137+ /// Return whether the URL includes credentials.
2138+ ///
2139+ /// A URL includes credentials if its username or password is not the empty string.
2140+ ///
2141+ /// # Examples
2142+ ///
2143+ /// ```
2144+ /// use url::Url;
2145+ /// # use url::ParseError;
2146+ ///
2147+ /// # fn run() -> Result<(), ParseError> {
2148+ /// let url = Url::parse("https://username:password@www.my_site.com")?;
2149+ /// assert!(url.includes_credentials());
2150+ ///
2151+ /// let url = Url::parse("https://username@www.my_site.com")?;
2152+ /// assert!(url.includes_credentials());
2153+ ///
2154+ /// let url = Url::parse("https://www.my_site.com")?;
2155+ /// assert!(!url.includes_credentials());
2156+ ///
2157+ /// let url = Url::parse("https://@www.my_site.com")?;
2158+ /// assert!(!url.includes_credentials());
2159+ /// # Ok(())
2160+ /// # }
2161+ /// # run().unwrap();
2162+ /// ```
2163+ pub fn includes_credentials ( & self ) -> bool {
2164+ self . username ( ) != "" || self . password ( ) . unwrap_or ( & "" ) != ""
2165+ }
2166+
21062167 /// Convert a file name as `std::path::Path` into an URL in the `file` scheme.
21072168 ///
21082169 /// This returns `Err` if the given path is not absolute or,
0 commit comments