This guide contains steps for upgrading crates in this project between major versions.
-
The minimum supported Rust version is now v1.33.0. Verify that you can bump your library or application to the same MSRV.
-
Url
no longer implementsstd::net::ToSocketAddrs
. You will instead need to explicitly callsocket_addrs
to convert yourUrl
to a type that implementsToSocketAddrs
.Note that v2.0 removed support for
std::net::ToSocketAddrs
with no replacement; thesocket_addrs
method was not added until v2.1.Before upgrading:
let url = Url::parse("http://github.com:80").unwrap(); let stream = TcpStream::connect(url).unwrap();
After upgrading:
let url = Url::parse("http://github.com:80").unwrap(); let addrs = url.socket_addrs(|| None).unwrap(); let stream = TcpStream::connect(addrs).unwrap();
Before upgrading:
let url = Url::parse("socks5://localhost").unwrap(); let stream = TcpStream::connect(url.with_default_port(|url| match url.scheme() { "socks5" => Ok(1080), _ => Err(()), })).unwrap();
After upgrading:
let url = Url::parse("http://github.com:80").unwrap(); let stream = TcpStream::connect(url.socket_addrs(|| match url.scheme() { "socks5" => Some(1080), _ => None, })).unwrap();
-
url_serde
is no longer required to useUrl
with Serde 1.x. Remove references tourl_serde
and enable theserde
feature instead.# Cargo.toml [dependencies] url = { version = "2.0", features = ["serde"] }
-
The
idna
andpercent_export
crates are no longer exported by theurl
crate. Depend on those crates directly instead. See below for additional breaking changes in the percent-export package.Before upgrading:
use url::percent_encoding::percent_decode;
After upgrading:
use percent_encoding::percent_decode;
-
Prepackaged encoding sets, like
QUERY_ENCODE_SET
andPATH_SEGMENT_ENCODE_SET
, are no longer provided. You will need to read the specifications relevant to your domain and construct your own encoding sets by using thepercent_encoding::AsciiSet
builder methods on either of the base encoding sets,percent_encoding::CONTROLS
orpercent_encoding::NON_ALPHANUMERIC
.Before upgrading:
use percent_encoding::QUERY_ENCODE_SET; percent_encoding::utf8_percent_encode(value, QUERY_ENCODE_SET);
After upgrading:
/// https://url.spec.whatwg.org/#query-state const QUERY: &AsciiSet = &CONTROLS.add(b' ').add(b'"').add(b'#').add(b'<').add(b'>'); percent_encoding::utf8_percent_encode(value, QUERY);
-
The fields of
Url
are now private because theUrl
constructor, parser, and setters maintain invariants that could be violated if you were to set the fields directly. Instead of accessing, for example,url.scheme
, use the getter method, such asurl.scheme()
. Instead of assigning directly to a field, for exampleurl.scheme = "https".to_string()
, use the setter method, such asurl.set_scheme("https").unwrap()
. (Some setters validate the new value and return aResult
that must be used). -
The methods of
Url
now return&str
instead ofString
, thus reducing allocations and making serialization cheap. -
The
path()
method onurl::Url
instances used to returnOption<&[String]>
; now it returns&str
. If you would like functionality more similar to the old behavior ofpath()
, usepath_segments()
that returnsOption<str::Split<char>>
.Before upgrading:
let issue_list_url = Url::parse( "https://github.com/rust-lang/rust/issues?labels=E-easy&state=open" ).unwrap(); assert_eq!(issue_list_url.path(), Some(&["rust-lang".to_string(), "rust".to_string(), "issues".to_string()][..]));
After upgrading:
let issue_list_url = Url::parse( "https://github.com/rust-lang/rust/issues?labels=E-easy&state=open" ).unwrap(); assert_eq!(issue_list_url.path(), "/rust-lang/rust/issues"); assert_eq!(issue_list_url.path_segments().map(|c| c.collect::<Vec<_>>()), Some(vec!["rust-lang", "rust", "issues"]));
-
The
path_mut()
method onurl::Url
instances that allowed modification of a URL's path has been replaced bypath_segments_mut()
.Before upgrading:
let mut url = Url::parse("https://github.com/rust-lang/rust").unwrap(); url.path_mut().unwrap().push("issues");
After upgrading:
let mut url = Url::parse("https://github.com/rust-lang/rust").unwrap(); url.path_segments_mut().unwrap().push("issues");
-
The
domain_mut()
method onurl::Url
instances that allowed modification of a URL's domain has been replaced byset_host()
andset_ip_host()
. -
The
host()
method onurl::Url
instances used to returnOption<&Host>
; now it returnsOption<Host<&str>>
. Theserialize_host()
method that returnedOption<String>
has been replaced by thehost_str()
method that returnsOption<&str>
. -
The
serialize()
method onurl::Url
instances that returnedString
has been replaced by anas_str()
method that returns&str
.Before upgrading:
let this_document = Url::parse("http://servo.github.io/rust-url/url/index.html").unwrap(); assert_eq!(this_document.serialize(), "http://servo.github.io/rust-url/url/index.html".to_string());
After upgrading:
let this_document = Url::parse("http://servo.github.io/rust-url/url/index.html").unwrap(); assert_eq!(this_document.as_str(), "http://servo.github.io/rust-url/url/index.html");
-
url::UrlParser
has been replaced byurl::Url::parse()
andurl::Url::join()
.Before upgrading:
let this_document = Url::parse("http://servo.github.io/rust-url/url/index.html").unwrap(); let css_url = UrlParser::new().base_url(&this_document).parse("../main.css").unwrap(); assert_eq!(css_url.serialize(), "http://servo.github.io/rust-url/main.css".to_string());
After upgrading:
let this_document = Url::parse("http://servo.github.io/rust-url/url/index.html").unwrap(); let css_url = this_document.join("../main.css").unwrap(); assert_eq!(css_url.as_str(), "http://servo.github.io/rust-url/main.css");
-
url::parse_path()
andurl::UrlParser::parse_path()
have been removed without replacement. As a workaround, you can give a base URL that you then ignore toourl::Url::parse()
.Before upgrading:
let (path, query, fragment) = url::parse_path("/foo/bar/../baz?q=42").unwrap(); assert_eq!(path, vec!["foo".to_string(), "baz".to_string()]); assert_eq!(query, Some("q=42".to_string())); assert_eq!(fragment, None);
After upgrading:
let base = Url::parse("http://example.com").unwrap(); let with_path = base.join("/foo/bar/../baz?q=42").unwrap(); assert_eq!(with_path.path(), "/foo/baz"); assert_eq!(with_path.query(), Some("q=42")); assert_eq!(with_path.fragment(), None);
-
The
url::form_urlencoded::serialize()
method has been replaced with theurl::form_urlencoded::Serializer
struct. Instead of callingserialize()
with key/value pairs, create a newSerializer
with a new string, call theextend_pairs()
method on theSerializer
instance with the key/value pairs as the argument, then callfinish()
.Before upgrading:
let form = url::form_urlencoded::serialize(form.iter().map(|(k, v)| { (&k[..], &v[..]) }));
After upgrading:
let form = url::form_urlencoded::Serializer::new(String::new()).extend_pairs( form.iter().map(|(k, v)| { (&k[..], &v[..]) }) ).finish();
-
The
set_query_from_pairs()
method onurl::Url
instances that took key/value pairs has been replaced withquery_pairs_mut()
, which allows you to modify theurl::Url
's query pairs.Before upgrading:
let mut url = Url::parse("https://duckduckgo.com/").unwrap(); let pairs = vec![ ("q", "test"), ("ia", "images"), ]; url.set_query_from_pairs(pairs.iter().map(|&(k, v)| { (&k[..], &v[..]) }));
After upgrading:
let mut url = Url::parse("https://duckduckgo.com/").unwrap(); let pairs = vec![ ("q", "test"), ("ia", "images"), ]; url.query_pairs_mut().clear().extend_pairs( pairs.iter().map(|&(k, v)| { (&k[..], &v[..]) }) );
-
url::SchemeData
, its variantsRelative
andNonRelative
, and the structurl::RelativeSchemeData
have been removed. Instead of matching on these variants to determine if you have a URL in a relative scheme such as HTTP versus a URL in a non-relative scheme as data, use thecannot_be_a_base()
method to determine which kind you have.Before upgrading:
match url.scheme_data { url::SchemeData::Relative(..) => {} url::SchemeData::NonRelative(..) => { return Err(human(format!("`{}` must have relative scheme \ data: {}", field, url))) } }
After upgrading:
if url.cannot_be_a_base() { return Err(human(format!("`{}` must have relative scheme \ data: {}", field, url))) }
-
The functions
url::whatwg_scheme_type_mapper()
, theSchemeType
enum, and thescheme_type_mapper()
method onurl::UrlParser
instances have been removed.SchemeType
had a method for getting thedefault_port()
; to replicate this functionality, use the methodport_or_known_default()
onurl::Url
instances. Theport_or_default()
method onurl::Url
instances has been removed; useport_or_known_default()
instead.Before upgrading:
let port = match whatwg_scheme_type_mapper(&url.scheme) { SchemeType::Relative(port) => port, _ => return Err(format!("Invalid special scheme: `{}`", raw_url.scheme)), };
After upgrading:
let port = match url.port_or_known_default() { Some(port) => port, _ => return Err(format!("Invalid special scheme: `{}`", url.scheme())), };
-
The following formatting utilities have been removed without replacement; look at their linked previous implementations if you would like to replicate the functionality in your code:
-
url::percent_encoding::percent_decode()
used to have a return type ofVec<u8>
; now it returns an iterator of decodedu8
bytes that also implementsInto<Cow<u8>>
. Use.into().to_owned()
to obtain aVec<u8>
. (.collect()
also works but might not be as efficient.) -
The
url::percent_encoding::EncodeSet
struct and constant instances used withurl::percent_encoding::percent_encode()
have been changed to structs that implement the traiturl::percent_encoding::EncodeSet
.SIMPLE_ENCODE_SET
,QUERY_ENCODE_SET
,DEFAULT_ENCODE_SET
, andUSERINFO_ENCODE_SET
have the same behavior.USERNAME_ENCODE_SET
andPASSWORD_ENCODE_SET
have been removed; useUSERINFO_ENCODE_SET
instead.HTTP_VALUE_ENCODE_SET
has been removed; an implementation of it in the new types can be found in hyper's source if you need to replicate this functionality in your code.FORM_URLENCODED_ENCODE_SET
has been removed; instead, use the functionality inurl::form_urlencoded
.PATH_SEGMENT_ENCODE_SET
has been added for use on '/'-separated path segments.
-
url::percent_encoding::percent_decode_to()
has been removed. Useurl::percent_encoding::percent_decode()
which returns an iterator. You can then use the iterator’scollect()
method or give it to some data structure’sextend()
method. -
A number of
ParseError
variants have changed. See the documentation for the current set. -
url::OpaqueOrigin::new()
andurl::Origin::UID(OpaqueOrigin)
have been replaced byurl::Origin::new_opaque()
andurl::Origin::Opaque(OpaqueOrigin)
, respectively.