@@ -1664,8 +1664,13 @@ impl Url {
1664
1664
self . set_host_internal ( Host :: parse_opaque ( host_substr) ?, None ) ;
1665
1665
}
1666
1666
} else if self . has_host ( ) {
1667
- if SchemeType :: from ( self . scheme ( ) ) . is_special ( ) {
1667
+ let scheme_type = SchemeType :: from ( self . scheme ( ) ) ;
1668
+ if scheme_type. is_special ( ) {
1668
1669
return Err ( ParseError :: EmptyHost ) ;
1670
+ } else {
1671
+ if self . serialization . len ( ) == self . path_start as usize {
1672
+ self . serialization . push ( '/' ) ;
1673
+ }
1669
1674
}
1670
1675
debug_assert ! ( self . byte_at( self . scheme_end) == b':' ) ;
1671
1676
debug_assert ! ( self . byte_at( self . path_start) == b'/' ) ;
@@ -1968,14 +1973,28 @@ impl Url {
1968
1973
///
1969
1974
/// # fn run() -> Result<(), ParseError> {
1970
1975
/// let mut url = Url::parse("https://example.net")?;
1971
- /// let result = url.set_scheme("foo ");
1972
- /// assert_eq!(url.as_str(), "foo ://example.net/");
1976
+ /// let result = url.set_scheme("http ");
1977
+ /// assert_eq!(url.as_str(), "http ://example.net/");
1973
1978
/// assert!(result.is_ok());
1974
1979
/// # Ok(())
1975
1980
/// # }
1976
1981
/// # run().unwrap();
1977
1982
/// ```
1983
+ /// Change the URL’s scheme from `foo` to `bar`:
1978
1984
///
1985
+ /// ```
1986
+ /// use url::Url;
1987
+ /// # use url::ParseError;
1988
+ ///
1989
+ /// # fn run() -> Result<(), ParseError> {
1990
+ /// let mut url = Url::parse("foo://example.net")?;
1991
+ /// let result = url.set_scheme("bar");
1992
+ /// assert_eq!(url.as_str(), "bar://example.net");
1993
+ /// assert!(result.is_ok());
1994
+ /// # Ok(())
1995
+ /// # }
1996
+ /// # run().unwrap();
1997
+ /// ```
1979
1998
///
1980
1999
/// Cannot change URL’s scheme from `https` to `foõ`:
1981
2000
///
@@ -2008,14 +2027,49 @@ impl Url {
2008
2027
/// # }
2009
2028
/// # run().unwrap();
2010
2029
/// ```
2030
+ /// Cannot change the URL’s scheme from `foo` to `https`:
2031
+ ///
2032
+ /// ```
2033
+ /// use url::Url;
2034
+ /// # use url::ParseError;
2035
+ ///
2036
+ /// # fn run() -> Result<(), ParseError> {
2037
+ /// let mut url = Url::parse("foo://example.net")?;
2038
+ /// let result = url.set_scheme("https");
2039
+ /// assert_eq!(url.as_str(), "foo://example.net");
2040
+ /// assert!(result.is_err());
2041
+ /// # Ok(())
2042
+ /// # }
2043
+ /// # run().unwrap();
2044
+ /// ```
2045
+ /// Cannot change the URL’s scheme from `http` to `foo`:
2046
+ ///
2047
+ /// ```
2048
+ /// use url::Url;
2049
+ /// # use url::ParseError;
2050
+ ///
2051
+ /// # fn run() -> Result<(), ParseError> {
2052
+ /// let mut url = Url::parse("http://example.net")?;
2053
+ /// let result = url.set_scheme("foo");
2054
+ /// assert_eq!(url.as_str(), "http://example.net/");
2055
+ /// assert!(result.is_err());
2056
+ /// # Ok(())
2057
+ /// # }
2058
+ /// # run().unwrap();
2059
+ /// ```
2011
2060
pub fn set_scheme ( & mut self , scheme : & str ) -> Result < ( ) , ( ) > {
2012
2061
let mut parser = Parser :: for_setter ( String :: new ( ) ) ;
2013
2062
let remaining = parser. parse_scheme ( parser:: Input :: new ( scheme) ) ?;
2014
2063
let new_scheme_type = SchemeType :: from ( & parser. serialization ) ;
2015
2064
let old_scheme_type = SchemeType :: from ( self . scheme ( ) ) ;
2016
- // Switching from special scheme to non special scheme
2017
- // and switching from file to non file is not allowed
2018
- if old_scheme_type != new_scheme_type {
2065
+ // If url’s scheme is a special scheme and buffer is not a special scheme, then return.
2066
+ if new_scheme_type. is_special ( ) && !old_scheme_type. is_special ( ) ||
2067
+ // If url’s scheme is not a special scheme and buffer is a special scheme, then return.
2068
+ !new_scheme_type. is_special ( ) && old_scheme_type. is_special ( ) ||
2069
+ // If url includes credentials or has a non-null port, and buffer is "file", then return.
2070
+ // If url’s scheme is "file" and its host is an empty host or null, then return.
2071
+ new_scheme_type. is_file ( ) && self . has_authority ( )
2072
+ {
2019
2073
return Err ( ( ) ) ;
2020
2074
}
2021
2075
0 commit comments