Lines Matching +full:url +full:- +full:parse
1 // Copyright 2013-2015 The rust-url developers.
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
11 rust-url is an implementation of the [URL Standard](http://url.spec.whatwg.org/)
12 for the [Rust](http://rust-lang.org/) programming language.
15 # URL parsing and data structures
17 First, URL parsing may fail for various reasons and therefore returns a `Result`.
20 use url::{Url, ParseError};
22 assert!(Url::parse("http://[:::1]") == Err(ParseError::InvalidIpv6Address))
25 Let’s parse a valid URL and look at its components.
28 use url::{Url, Host, Position};
29 # use url::ParseError;
30 # fn run() -> Result<(), ParseError> {
31 let issue_list_url = Url::parse(
32 "https://github.com/rust-lang/rust/issues?labels=E-easy&state=open"
42 assert!(issue_list_url.path() == "/rust-lang/rust/issues");
44 Some(vec!["rust-lang", "rust", "issues"]));
45 assert!(issue_list_url.query() == Some("labels=E-easy&state=open"));
46 assert!(&issue_list_url[Position::BeforePath..] == "/rust-lang/rust/issues?labels=E-easy&state=open…
54 Some URLs are said to be *cannot-be-a-base*:
56 and their "path" is an arbitrary string rather than slash-separated segments:
59 use url::Url;
60 # use url::ParseError;
62 # fn run() -> Result<(), ParseError> {
63 let data_url = Url::parse("data:text/plain,Hello?World#")?;
78 Enable the `serde` feature to include `Deserialize` and `Serialize` implementations for `url::Url`.
80 # Base URL
82 Many contexts allow URL *references* that can be relative to a *base URL*:
91 use url::{Url, ParseError};
93 assert!(Url::parse("../main.css") == Err(ParseError::RelativeUrlWithoutBase))
96 Use the `join` method on an `Url` to use it as a base URL:
99 use url::Url;
100 # use url::ParseError;
102 # fn run() -> Result<(), ParseError> {
103 let this_document = Url::parse("http://servo.github.io/rust-url/url/index.html")?;
105 assert_eq!(css_url.as_str(), "http://servo.github.io/rust-url/main.css");
113 If you enable the `serde` feature, [`Url`](struct.Url.html) will implement
119 url = { version = "2", features = ["serde"] }
124 #![doc(html_root_url = "https://docs.rs/url/2.3.1")]
128 debugger_visualizer(natvis_file = "../../debug_metadata/url.natvis")
168 /// A parsed URL record.
170 pub struct Url { struct
171 /// Syntax in pseudo-BNF:
173 /// url = scheme ":" [ hierarchical | non-hierarchical ] [ "?" query ]? [ "#" fragment ]?
174 /// non-hierarchical = non-hierarchical-path
175 /// non-hierarchical-path = /* Does not start with "/" */
176 /// hierarchical = authority? hierarchical-path
179 /// hierarchical-path = [ "/" path-segment ]+
194 /// Full configuration for the URL parser.
197 base_url: Option<&'a Url>, argument
203 /// Change the base URL
204 pub fn base_url(mut self, new: Option<&'a Url>) -> Self { in base_url()
211 pub fn encoding_override(mut self, new: EncodingOverride<'a>) -> Self { in encoding_override()
216 /// Call the provided function or closure for a non-fatal `SyntaxViolation`
224 /// use url::{Url, SyntaxViolation};
225 /// # use url::ParseError;
226 /// # fn run() -> Result<(), url::ParseError> {
228 /// let url = Url::options()
230 /// .parse("https:////example.com")?;
231 /// assert_eq!(url.as_str(), "https://example.com/");
238 pub fn syntax_violation_callback(mut self, new: Option<&'a dyn Fn(SyntaxViolation)>) -> Self { in syntax_violation_callback()
243 /// Parse an URL string with the configuration so far.
244 pub fn parse(self, input: &str) -> Result<Url, crate::ParseError> { in parse() method
256 impl Url { impl
257 /// Parse an absolute URL from a string.
262 /// use url::Url;
263 /// # use url::ParseError;
265 /// # fn run() -> Result<(), ParseError> {
266 /// let url = Url::parse("https://example.net")?;
274 /// If the function can not parse an absolute URL from the given string,
279 pub fn parse(input: &str) -> Result<Url, crate::ParseError> { in parse() method
280 Url::options().parse(input) in parse()
283 /// Parse an absolute URL from a string and add params to its query string.
290 /// use url::Url;
291 /// # use url::ParseError;
293 /// # fn run() -> Result<(), ParseError> {
294 /// let url = Url::parse_with_params("https://example.net?dont=clobberme",
296 /// assert_eq!("https://example.net/?dont=clobberme&lang=rust&browser=servo", url.as_str());
304 /// If the function can not parse an absolute URL from the given string,
309 pub fn parse_with_params<I, K, V>(input: &str, iter: I) -> Result<Url, crate::ParseError> in parse_with_params() argument
316 let mut url = Url::options().parse(input); in parse_with_params() localVariable
318 if let Ok(ref mut url) = url { in parse_with_params()
319 url.query_pairs_mut().extend_pairs(iter); in parse_with_params()
322 url in parse_with_params()
325 /// Parse a string as an URL, with this URL as the base URL.
336 /// use url::Url;
337 /// # use url::ParseError;
339 /// # fn run() -> Result<(), ParseError> {
340 /// let base = Url::parse("https://example.net/a/b.html")?;
341 /// let url = base.join("c.png")?;
342 /// assert_eq!(url.as_str(), "https://example.net/a/c.png"); // Not /a/b.html/c.png
344 /// let base = Url::parse("https://example.net/a/b/")?;
345 /// let url = base.join("c.png")?;
346 /// assert_eq!(url.as_str(), "https://example.net/a/b/c.png");
354 /// If the function can not parse an URL from the given string
355 /// with this URL as the base URL, a [`ParseError`] variant will be returned.
360 pub fn join(&self, input: &str) -> Result<Url, crate::ParseError> { in join() argument
361 Url::options().base_url(Some(self)).parse(input) in join()
364 /// Creates a relative URL if possible, with this URL as the base URL.
371 /// use url::Url;
372 /// # use url::ParseError;
374 /// # fn run() -> Result<(), ParseError> {
375 /// let base = Url::parse("https://example.net/a/b.html")?;
376 /// let url = Url::parse("https://example.net/a/c.png")?;
377 /// let relative = base.make_relative(&url);
380 /// let base = Url::parse("https://example.net/a/b/")?;
381 /// let url = Url::parse("https://example.net/a/b/c.png")?;
382 /// let relative = base.make_relative(&url);
385 /// let base = Url::parse("https://example.net/a/b/")?;
386 /// let url = Url::parse("https://example.net/a/d/c.png")?;
387 /// let relative = base.make_relative(&url);
390 /// let base = Url::parse("https://example.net/a/b.html?c=d")?;
391 /// let url = Url::parse("https://example.net/a/b.html?e=f")?;
392 /// let relative = base.make_relative(&url);
401 /// If this URL can't be a base for the given URL, `None` is returned.
405 pub fn make_relative(&self, url: &Url) -> Option<String> { in make_relative()
411 if self.scheme() != url.scheme() || self.host() != url.host() || self.port() != url.port() { in make_relative()
421 fn extract_path_filename(s: &str) -> (&str, &str) { in make_relative()
432 let (url_path, url_filename) = extract_path_filename(url.path()); in make_relative()
483 if let Some(query) = url.query() { in make_relative()
488 if let Some(fragment) = url.fragment() { in make_relative()
496 /// Return a default `ParseOptions` that can fully configure the URL parser.
500 /// Get default `ParseOptions`, then change base url
503 /// use url::Url;
504 /// # use url::ParseError;
505 /// # fn run() -> Result<(), ParseError> {
506 /// let options = Url::options();
507 /// let api = Url::parse("https://api.example.com")?;
509 /// let version_url = base_url.parse("version.json")?;
515 pub fn options<'a>() -> ParseOptions<'a> { in options()
523 /// Return the serialization of this URL.
525 /// This is fast since that serialization is already stored in the `Url` struct.
530 /// use url::Url;
531 /// # use url::ParseError;
533 /// # fn run() -> Result<(), ParseError> {
535 /// let url = Url::parse(url_str)?;
536 /// assert_eq!(url.as_str(), url_str);
542 pub fn as_str(&self) -> &str { in as_str()
546 /// Return the serialization of this URL.
548 /// This consumes the `Url` and takes ownership of the `String` stored in it.
553 /// use url::Url;
554 /// # use url::ParseError;
556 /// # fn run() -> Result<(), ParseError> {
558 /// let url = Url::parse(url_str)?;
559 /// assert_eq!(String::from(url), url_str);
566 pub fn into_string(self) -> String { in into_string()
572 /// Methods of the `Url` struct assume a number of invariants.
574 /// This is for testing rust-url itself.
576 pub fn check_invariants(&self) -> Result<(), String> { in check_invariants()
581 "!( {} ) for URL {:?}", in check_invariants()
595 return Err(format!("{:?} != {:?} ({} != {}) for URL {:?}", in check_invariants()
608 .all(|c| matches!(c, 'a'..='z' | 'A'..='Z' | '0'..='9' | '+' | '-' | '.'))); in check_invariants()
612 // URL with authority in check_invariants()
617 assert_eq!(self.byte_at(self.host_start - 1), b'@'); in check_invariants()
646 Some(port_str.parse::<u16>().expect("Couldn't parse port?")) in check_invariants()
654 // Anarchist URL (no authority) in check_invariants()
674 let other = Url::parse(self.as_str()).expect("Failed to parse myself?"); in check_invariants()
682 // XXX No host round-trips to empty host. in check_invariants()
683 // See https://github.com/whatwg/url/issues/79 in check_invariants()
693 /// Return the origin of this URL (<https://url.spec.whatwg.org/#origin>)
696 /// `url.origin() != url.origin()`.
700 /// URL with `ftp` scheme:
703 /// use url::{Host, Origin, Url};
704 /// # use url::ParseError;
706 /// # fn run() -> Result<(), ParseError> {
707 /// let url = Url::parse("ftp://example.com/foo")?;
708 /// assert_eq!(url.origin(),
717 /// URL with `blob` scheme:
720 /// use url::{Host, Origin, Url};
721 /// # use url::ParseError;
723 /// # fn run() -> Result<(), ParseError> {
724 /// let url = Url::parse("blob:https://example.com/foo")?;
725 /// assert_eq!(url.origin(),
734 /// URL with `file` scheme:
737 /// use url::{Host, Origin, Url};
738 /// # use url::ParseError;
740 /// # fn run() -> Result<(), ParseError> {
741 /// let url = Url::parse("file:///tmp/foo")?;
742 /// assert!(!url.origin().is_tuple());
744 /// let other_url = Url::parse("file:///tmp/foo")?;
745 /// assert!(url.origin() != other_url.origin());
751 /// URL with other scheme:
754 /// use url::{Host, Origin, Url};
755 /// # use url::ParseError;
757 /// # fn run() -> Result<(), ParseError> {
758 /// let url = Url::parse("foo:bar")?;
759 /// assert!(!url.origin().is_tuple());
765 pub fn origin(&self) -> Origin { in origin()
769 /// Return the scheme of this URL, lower-cased, as an ASCII string without the ':' delimiter.
774 /// use url::Url;
775 /// # use url::ParseError;
777 /// # fn run() -> Result<(), ParseError> {
778 /// let url = Url::parse("file:///tmp/foo")?;
779 /// assert_eq!(url.scheme(), "file");
785 pub fn scheme(&self) -> &str { in scheme()
789 /// Return whether the URL has an 'authority',
792 /// URLs that do *not* are either path-only like `unix:/run/foo.socket`
793 /// or cannot-be-a-base like `data:text/plain,Stuff`.
798 /// use url::Url;
799 /// # use url::ParseError;
801 /// # fn run() -> Result<(), ParseError> {
802 /// let url = Url::parse("ftp://rms@example.com")?;
803 /// assert!(url.has_authority());
805 /// let url = Url::parse("unix:/run/foo.socket")?;
806 /// assert!(!url.has_authority());
808 /// let url = Url::parse("data:text/plain,Stuff")?;
809 /// assert!(!url.has_authority());
815 pub fn has_authority(&self) -> bool { in has_authority()
820 /// Return whether this URL is a cannot-be-a-base URL,
821 /// meaning that parsing a relative URL string with this URL as the base will return an error.
829 /// use url::Url;
830 /// # use url::ParseError;
832 /// # fn run() -> Result<(), ParseError> {
833 /// let url = Url::parse("ftp://rms@example.com")?;
834 /// assert!(!url.cannot_be_a_base());
836 /// let url = Url::parse("unix:/run/foo.socket")?;
837 /// assert!(!url.cannot_be_a_base());
839 /// let url = Url::parse("data:text/plain,Stuff")?;
840 /// assert!(url.cannot_be_a_base());
846 pub fn cannot_be_a_base(&self) -> bool { in cannot_be_a_base()
850 /// Return the username for this URL (typically the empty string)
851 /// as a percent-encoded ASCII string.
856 /// use url::Url;
857 /// # use url::ParseError;
859 /// # fn run() -> Result<(), ParseError> {
860 /// let url = Url::parse("ftp://rms@example.com")?;
861 /// assert_eq!(url.username(), "rms");
863 /// let url = Url::parse("ftp://:secret123@example.com")?;
864 /// assert_eq!(url.username(), "");
866 /// let url = Url::parse("https://example.com")?;
867 /// assert_eq!(url.username(), "");
872 pub fn username(&self) -> &str { in username()
881 /// Return the password for this URL, if any, as a percent-encoded ASCII string.
886 /// use url::Url;
887 /// # use url::ParseError;
889 /// # fn run() -> Result<(), ParseError> {
890 /// let url = Url::parse("ftp://rms:secret123@example.com")?;
891 /// assert_eq!(url.password(), Some("secret123"));
893 /// let url = Url::parse("ftp://:secret123@example.com")?;
894 /// assert_eq!(url.password(), Some("secret123"));
896 /// let url = Url::parse("ftp://rms@example.com")?;
897 /// assert_eq!(url.password(), None);
899 /// let url = Url::parse("https://example.com")?;
900 /// assert_eq!(url.password(), None);
905 pub fn password(&self) -> Option<&str> { in password()
912 debug_assert!(self.byte_at(self.host_start - 1) == b'@'); in password()
913 Some(self.slice(self.username_end + 1..self.host_start - 1)) in password()
919 /// Equivalent to `url.host().is_some()`.
924 /// use url::Url;
925 /// # use url::ParseError;
927 /// # fn run() -> Result<(), ParseError> {
928 /// let url = Url::parse("ftp://rms@example.com")?;
929 /// assert!(url.has_host());
931 /// let url = Url::parse("unix:/run/foo.socket")?;
932 /// assert!(!url.has_host());
934 /// let url = Url::parse("data:text/plain,Stuff")?;
935 /// assert!(!url.has_host());
940 pub fn has_host(&self) -> bool { in has_host()
944 /// Return the string representation of the host (domain or IP address) for this URL, if any.
946 /// Non-ASCII domains are punycode-encoded per IDNA if this is the host
947 /// of a special URL, or percent encoded for non-special URLs.
950 /// Cannot-be-a-base URLs (typical of `data:` and `mailto:`) and some `file:` URLs
958 /// use url::Url;
959 /// # use url::ParseError;
961 /// # fn run() -> Result<(), ParseError> {
962 /// let url = Url::parse("https://127.0.0.1/index.html")?;
963 /// assert_eq!(url.host_str(), Some("127.0.0.1"));
965 /// let url = Url::parse("ftp://rms@example.com")?;
966 /// assert_eq!(url.host_str(), Some("example.com"));
968 /// let url = Url::parse("unix:/run/foo.socket")?;
969 /// assert_eq!(url.host_str(), None);
971 /// let url = Url::parse("data:text/plain,Stuff")?;
972 /// assert_eq!(url.host_str(), None);
977 pub fn host_str(&self) -> Option<&str> { in host_str()
985 /// Return the parsed representation of the host for this URL.
986 /// Non-ASCII domain labels are punycode-encoded per IDNA if this is the host
987 /// of a special URL, or percent encoded for non-special URLs.
989 /// Cannot-be-a-base URLs (typical of `data:` and `mailto:`) and some `file:` URLs
997 /// use url::Url;
998 /// # use url::ParseError;
1000 /// # fn run() -> Result<(), ParseError> {
1001 /// let url = Url::parse("https://127.0.0.1/index.html")?;
1002 /// assert!(url.host().is_some());
1004 /// let url = Url::parse("ftp://rms@example.com")?;
1005 /// assert!(url.host().is_some());
1007 /// let url = Url::parse("unix:/run/foo.socket")?;
1008 /// assert!(url.host().is_none());
1010 /// let url = Url::parse("data:text/plain,Stuff")?;
1011 /// assert!(url.host().is_none());
1016 pub fn host(&self) -> Option<Host<&str>> { in host()
1025 /// If this URL has a host and it is a domain name (not an IP address), return it.
1026 /// Non-ASCII domains are punycode-encoded per IDNA if this is the host
1027 /// of a special URL, or percent encoded for non-special URLs.
1032 /// use url::Url;
1033 /// # use url::ParseError;
1035 /// # fn run() -> Result<(), ParseError> {
1036 /// let url = Url::parse("https://127.0.0.1/")?;
1037 /// assert_eq!(url.domain(), None);
1039 /// let url = Url::parse("mailto:rms@example.net")?;
1040 /// assert_eq!(url.domain(), None);
1042 /// let url = Url::parse("https://example.com/")?;
1043 /// assert_eq!(url.domain(), Some("example.com"));
1048 pub fn domain(&self) -> Option<&str> { in domain()
1055 /// Return the port number for this URL, if any.
1063 /// use url::Url;
1064 /// # use url::ParseError;
1066 /// # fn run() -> Result<(), ParseError> {
1067 /// let url = Url::parse("https://example.com")?;
1068 /// assert_eq!(url.port(), None);
1070 /// let url = Url::parse("https://example.com:443/")?;
1071 /// assert_eq!(url.port(), None);
1073 /// let url = Url::parse("ssh://example.com:22")?;
1074 /// assert_eq!(url.port(), Some(22));
1080 pub fn port(&self) -> Option<u16> { in port()
1084 /// Return the port number for this URL, or the default port number if it is known.
1090 /// For other schemes, it is the same as `Url::port()`.
1095 /// use url::Url;
1096 /// # use url::ParseError;
1098 /// # fn run() -> Result<(), ParseError> {
1099 /// let url = Url::parse("foo://example.com")?;
1100 /// assert_eq!(url.port_or_known_default(), None);
1102 /// let url = Url::parse("foo://example.com:1456")?;
1103 /// assert_eq!(url.port_or_known_default(), Some(1456));
1105 /// let url = Url::parse("https://example.com")?;
1106 /// assert_eq!(url.port_or_known_default(), Some(443));
1112 pub fn port_or_known_default(&self) -> Option<u16> { in port_or_known_default()
1116 /// Resolve a URL’s host and port number to `SocketAddr`.
1118 /// If the URL has the default port number of a scheme that is unknown to this library,
1120 /// In non-example code this should be implemented either simply as `|| None`,
1121 /// or by matching on the URL’s `.scheme()`.
1128 /// let url = url::Url::parse("https://example.net/").unwrap();
1129 /// let addrs = url.socket_addrs(|| None).unwrap();
1135 /// /// With application-specific known default port numbers
1136 /// fn socket_addrs(url: url::Url) -> std::io::Result<Vec<std::net::SocketAddr>> {
1137 /// url.socket_addrs(|| match url.scheme() {
1145 default_port_number: impl Fn() -> Option<u16>, in socket_addrs()
1146 ) -> io::Result<Vec<SocketAddr>> { in socket_addrs()
1150 …// https://github.com/rust-lang/rfcs/blob/master/text/1951-expand-impl-trait.md#scoping-for-type-a… in socket_addrs()
1155 fn io_result<T>(opt: Option<T>, message: &str) -> io::Result<T> { in socket_addrs()
1159 let host = io_result(self.host(), "No host name in the URL")?; in socket_addrs()
1162 "No port number in the URL", in socket_addrs()
1171 /// Return the path for this URL, as a percent-encoded ASCII string.
1172 /// For cannot-be-a-base URLs, this is an arbitrary string that doesn’t start with '/'.
1174 /// and continues with slash-separated path segments.
1179 /// use url::{Url, ParseError};
1181 /// # fn run() -> Result<(), ParseError> {
1182 /// let url = Url::parse("https://example.com/api/versions?page=2")?;
1183 /// assert_eq!(url.path(), "/api/versions");
1185 /// let url = Url::parse("https://example.com")?;
1186 /// assert_eq!(url.path(), "/");
1188 /// let url = Url::parse("https://example.com/countries/việt nam")?;
1189 /// assert_eq!(url.path(), "/countries/vi%E1%BB%87t%20nam");
1194 pub fn path(&self) -> &str { in path()
1203 /// Unless this URL is cannot-be-a-base,
1204 /// return an iterator of '/' slash-separated path segments,
1205 /// each as a percent-encoded ASCII string.
1207 /// Return `None` for cannot-be-a-base URLs.
1215 /// use url::Url;
1218 /// # fn run() -> Result<(), Box<dyn Error>> {
1219 /// let url = Url::parse("https://example.com/foo/bar")?;
1220 /// let mut path_segments = url.path_segments().ok_or_else(|| "cannot be base")?;
1225 /// let url = Url::parse("https://example.com")?;
1226 /// let mut path_segments = url.path_segments().ok_or_else(|| "cannot be base")?;
1230 /// let url = Url::parse("data:text/plain,HelloWorld")?;
1231 /// assert!(url.path_segments().is_none());
1233 /// let url = Url::parse("https://example.com/countries/việt nam")?;
1234 /// let mut path_segments = url.path_segments().ok_or_else(|| "cannot be base")?;
1241 pub fn path_segments(&self) -> Option<str::Split<'_, char>> { in path_segments()
1246 /// Return this URL’s query string, if any, as a percent-encoded ASCII string.
1251 /// use url::Url;
1252 /// # use url::ParseError;
1254 /// fn run() -> Result<(), ParseError> {
1255 /// let url = Url::parse("https://example.com/products?page=2")?;
1256 /// let query = url.query();
1259 /// let url = Url::parse("https://example.com/products")?;
1260 /// let query = url.query();
1263 /// let url = Url::parse("https://example.com/?country=español")?;
1264 /// let query = url.query();
1270 pub fn query(&self) -> Option<&str> { in query()
1284 /// Parse the URL’s query string, if any, as `application/x-www-form-urlencoded`
1292 /// use url::Url;
1293 /// # use url::ParseError;
1295 /// # fn run() -> Result<(), ParseError> {
1296 /// let url = Url::parse("https://example.com/products?page=2&sort=desc")?;
1297 /// let mut pairs = url.query_pairs();
1309 pub fn query_pairs(&self) -> form_urlencoded::Parse<'_> { in query_pairs()
1310 form_urlencoded::parse(self.query().unwrap_or("").as_bytes()) in query_pairs()
1313 /// Return this URL’s fragment identifier, if any.
1315 /// A fragment is the part of the URL after the `#` symbol.
1322 /// of a URL to the server.
1324 /// **Note:** the parser did *not* percent-encode this component,
1325 /// but the input may have been percent-encoded already.
1330 /// use url::Url;
1331 /// # use url::ParseError;
1333 /// # fn run() -> Result<(), ParseError> {
1334 /// let url = Url::parse("https://example.com/data.csv#row=4")?;
1336 /// assert_eq!(url.fragment(), Some("row=4"));
1338 /// let url = Url::parse("https://example.com/data.csv#cell=4,1-6,2")?;
1340 /// assert_eq!(url.fragment(), Some("cell=4,1-6,2"));
1345 pub fn fragment(&self) -> Option<&str> { in fragment()
1352 fn mutate<F: FnOnce(&mut Parser<'_>) -> R, R>(&mut self, f: F) -> R { in mutate()
1359 /// Change this URL’s fragment identifier.
1364 /// use url::Url;
1365 /// # use url::ParseError;
1367 /// # fn run() -> Result<(), ParseError> {
1368 /// let mut url = Url::parse("https://example.com/data.csv")?;
1369 /// assert_eq!(url.as_str(), "https://example.com/data.csv");
1371 /// url.set_fragment(Some("cell=4,1-6,2"));
1372 /// assert_eq!(url.as_str(), "https://example.com/data.csv#cell=4,1-6,2");
1373 /// assert_eq!(url.fragment(), Some("cell=4,1-6,2"));
1375 /// url.set_fragment(None);
1376 /// assert_eq!(url.as_str(), "https://example.com/data.csv");
1377 /// assert!(url.fragment().is_none());
1398 fn take_fragment(&mut self) -> Option<String> { in take_fragment()
1416 /// Change this URL’s query string.
1421 /// use url::Url;
1422 /// # use url::ParseError;
1424 /// # fn run() -> Result<(), ParseError> {
1425 /// let mut url = Url::parse("https://example.com/products")?;
1426 /// assert_eq!(url.as_str(), "https://example.com/products");
1428 /// url.set_query(Some("page=2"));
1429 /// assert_eq!(url.as_str(), "https://example.com/products?page=2");
1430 /// assert_eq!(url.query(), Some("page=2"));
1462 /// Manipulate this URL’s query string, viewed as a sequence of name/value pairs
1463 /// in `application/x-www-form-urlencoded` syntax.
1465 /// The return value has a method-chaining API:
1468 /// # use url::{Url, ParseError};
1470 /// # fn run() -> Result<(), ParseError> {
1471 /// let mut url = Url::parse("https://example.net?lang=fr#nav")?;
1472 /// assert_eq!(url.query(), Some("lang=fr"));
1474 /// url.query_pairs_mut().append_pair("foo", "bar");
1475 /// assert_eq!(url.query(), Some("lang=fr&foo=bar"));
1476 /// assert_eq!(url.as_str(), "https://example.net/?lang=fr&foo=bar#nav");
1478 /// url.query_pairs_mut()
1482 /// assert_eq!(url.query(), Some("foo=bar+%26+baz&saisons=%C3%89t%C3%A9%2Bhiver"));
1483 /// assert_eq!(url.as_str(),
1490 /// Note: `url.query_pairs_mut().clear();` is equivalent to `url.set_query(Some(""))`,
1491 /// not `url.set_query(None)`.
1493 /// The state of `Url` is unspecified if this return value is leaked without being dropped.
1494 pub fn query_pairs_mut(&mut self) -> form_urlencoded::Serializer<'_, UrlQuery<'_>> { in query_pairs_mut()
1508 url: Some(self), in query_pairs_mut()
1514 fn take_after_path(&mut self) -> String { in take_after_path()
1525 /// Change this URL’s path.
1530 /// use url::Url;
1531 /// # use url::ParseError;
1533 /// # fn run() -> Result<(), ParseError> {
1534 /// let mut url = Url::parse("https://example.com")?;
1535 /// url.set_path("api/comments");
1536 /// assert_eq!(url.as_str(), "https://example.com/api/comments");
1537 /// assert_eq!(url.path(), "/api/comments");
1539 /// let mut url = Url::parse("https://example.com/api")?;
1540 /// url.set_path("data/report.csv");
1541 /// assert_eq!(url.as_str(), "https://example.com/data/report.csv");
1542 /// assert_eq!(url.path(), "/data/report.csv");
1544 /// // `set_path` percent-encodes the given string if it's not already percent-encoded.
1545 /// let mut url = Url::parse("https://example.com")?;
1546 /// url.set_path("api/some comments");
1547 /// assert_eq!(url.as_str(), "https://example.com/api/some%20comments");
1548 /// assert_eq!(url.path(), "/api/some%20comments");
1550 /// // `set_path` will not double percent-encode the string if it's already percent-encoded.
1551 /// let mut url = Url::parse("https://example.com")?;
1552 /// url.set_path("api/some%20comments");
1553 /// assert_eq!(url.as_str(), "https://example.com/api/some%20comments");
1554 /// assert_eq!(url.path(), "/api/some%20comments");
1581 /// Return an object with methods to manipulate this URL’s path segments.
1583 /// Return `Err(())` if this URL is cannot-be-a-base.
1585 pub fn path_segments_mut(&mut self) -> Result<PathSegmentsMut<'_>, ()> { in path_segments_mut()
1596 *index -= old_after_path_position; in restore_after_path()
1608 /// Change this URL’s port number.
1612 /// If this URL is cannot-be-a-base, does not have a host, or has the `file` scheme;
1618 /// use url::Url;
1621 /// # fn run() -> Result<(), Box<dyn Error>> {
1622 /// let mut url = Url::parse("ssh://example.net:2048/")?;
1624 /// url.set_port(Some(4096)).map_err(|_| "cannot be base")?;
1625 /// assert_eq!(url.as_str(), "ssh://example.net:4096/");
1627 /// url.set_port(None).map_err(|_| "cannot be base")?;
1628 /// assert_eq!(url.as_str(), "ssh://example.net/");
1637 /// use url::Url;
1640 /// # fn run() -> Result<(), Box<dyn Error>> {
1641 /// let mut url = Url::parse("https://example.org/")?;
1643 /// url.set_port(Some(443)).map_err(|_| "cannot be base")?;
1644 /// assert!(url.port().is_none());
1650 /// Cannot set port for cannot-be-a-base URLs:
1653 /// use url::Url;
1654 /// # use url::ParseError;
1656 /// # fn run() -> Result<(), ParseError> {
1657 /// let mut url = Url::parse("mailto:rms@example.net")?;
1659 /// let result = url.set_port(Some(80));
1662 /// let result = url.set_port(None);
1669 pub fn set_port(&mut self, mut port: Option<u16>) -> Result<(), ()> { in set_port()
1687 let offset = self.path_start - self.host_end; in set_port_internal()
1690 *index -= offset in set_port_internal()
1693 *index -= offset in set_port_internal()
1705 *index -= old_path_start; in set_port_internal()
1720 /// Change this URL’s host.
1730 /// use url::Url;
1731 /// # use url::ParseError;
1733 /// # fn run() -> Result<(), ParseError> {
1734 /// let mut url = Url::parse("https://example.net")?;
1735 /// let result = url.set_host(Some("rust-lang.org"));
1737 /// assert_eq!(url.as_str(), "https://rust-lang.org/");
1746 /// use url::Url;
1747 /// # use url::ParseError;
1749 /// # fn run() -> Result<(), ParseError> {
1750 /// let mut url = Url::parse("foo://example.net")?;
1751 /// let result = url.set_host(None);
1753 /// assert_eq!(url.as_str(), "foo:/");
1762 /// use url::Url;
1763 /// # use url::ParseError;
1765 /// # fn run() -> Result<(), ParseError> {
1766 /// let mut url = Url::parse("https://example.net")?;
1767 /// let result = url.set_host(None);
1769 /// assert_eq!(url.as_str(), "https://example.net/");
1775 /// Cannot change or remove host for cannot-be-a-base URLs:
1778 /// use url::Url;
1779 /// # use url::ParseError;
1781 /// # fn run() -> Result<(), ParseError> {
1782 /// let mut url = Url::parse("mailto:rms@example.net")?;
1784 /// let result = url.set_host(Some("rust-lang.org"));
1786 /// assert_eq!(url.as_str(), "mailto:rms@example.net");
1788 /// let result = url.set_host(None);
1790 /// assert_eq!(url.as_str(), "mailto:rms@example.net");
1798 /// If this URL is cannot-be-a-base or there is an error parsing the given `host`,
1802 pub fn set_host(&mut self, host: Option<&str>) -> Result<(), ParseError> { in set_host()
1829 self.set_host_internal(Host::parse(host_substr)?, None); in set_host()
1850 let offset = self.path_start - new_path_start; in set_host()
1857 *index -= offset in set_host()
1860 *index -= offset in set_host()
1897 *index -= old_suffix_pos; in set_host_internal()
1909 /// Change this URL’s host to the given IP address.
1911 /// If this URL is cannot-be-a-base, do nothing and return `Err`.
1913 /// Compared to `Url::set_host`, this skips the host parser.
1918 /// use url::{Url, ParseError};
1920 /// # fn run() -> Result<(), ParseError> {
1921 /// let mut url = Url::parse("http://example.com")?;
1922 /// url.set_ip_host("127.0.0.1".parse().unwrap());
1923 /// assert_eq!(url.host_str(), Some("127.0.0.1"));
1924 /// assert_eq!(url.as_str(), "http://127.0.0.1/");
1930 /// Cannot change URL's from mailto(cannot-be-base) to ip:
1933 /// use url::{Url, ParseError};
1935 /// # fn run() -> Result<(), ParseError> {
1936 /// let mut url = Url::parse("mailto:rms@example.com")?;
1937 /// let result = url.set_ip_host("127.0.0.1".parse().unwrap());
1939 /// assert_eq!(url.as_str(), "mailto:rms@example.com");
1947 pub fn set_ip_host(&mut self, address: IpAddr) -> Result<(), ()> { in set_ip_host()
1960 /// Change this URL’s password.
1962 /// If this URL is cannot-be-a-base or does not have a host, do nothing and return `Err`.
1967 /// use url::{Url, ParseError};
1969 /// # fn run() -> Result<(), ParseError> {
1970 /// let mut url = Url::parse("mailto:rmz@example.com")?;
1971 /// let result = url.set_password(Some("secret_password"));
1974 /// let mut url = Url::parse("ftp://user1:secret1@example.com")?;
1975 /// let result = url.set_password(Some("secret_password"));
1976 /// assert_eq!(url.password(), Some("secret_password"));
1978 /// let mut url = Url::parse("ftp://user2:@example.com")?;
1979 /// let result = url.set_password(Some("secret2"));
1981 /// assert_eq!(url.password(), Some("secret2"));
1987 pub fn set_password(&mut self, password: Option<&str>) -> Result<(), ()> { in set_password()
2003 *index -= old_host_start; in set_password()
2019 let has_username_or_password = self.byte_at(self.host_start - 1) == b'@'; in set_password()
2027 self.host_start - 1 // Keep the '@' to separate the username from the host in set_password()
2030 let offset = end - start; in set_password()
2031 self.host_start -= offset; in set_password()
2032 self.host_end -= offset; in set_password()
2033 self.path_start -= offset; in set_password()
2035 *index -= offset in set_password()
2038 *index -= offset in set_password()
2044 /// Change this URL’s username.
2046 /// If this URL is cannot-be-a-base or does not have a host, do nothing and return `Err`.
2049 /// Cannot setup username from mailto(cannot-be-base)
2052 /// use url::{Url, ParseError};
2054 /// # fn run() -> Result<(), ParseError> {
2055 /// let mut url = Url::parse("mailto:rmz@example.com")?;
2056 /// let result = url.set_username("user1");
2057 /// assert_eq!(url.as_str(), "mailto:rmz@example.com");
2067 /// use url::{Url, ParseError};
2069 /// # fn run() -> Result<(), ParseError> {
2070 /// let mut url = Url::parse("ftp://:secre1@example.com/")?;
2071 /// let result = url.set_username("user1");
2073 /// assert_eq!(url.username(), "user1");
2074 /// assert_eq!(url.as_str(), "ftp://user1:secre1@example.com/");
2080 pub fn set_username(&mut self, username: &str) -> Result<(), ()> { in set_username()
2116 *index -= removed_bytes; in set_username()
2131 /// Change this URL’s scheme.
2135 /// * If the new scheme is not in `[a-zA-Z][a-zA-Z0-9+.-]+`
2136 /// * If this URL is cannot-be-a-base and the new scheme is one of
2140 /// * If the new scheme is `file` and this URL includes credentials
2141 /// or has a non-null port
2142 /// * If this URL's scheme is `file` and its host is empty or null
2144 /// See also [the URL specification's section on legal scheme state
2145 /// overrides](https://url.spec.whatwg.org/#scheme-state).
2149 /// Change the URL’s scheme from `https` to `http`:
2152 /// use url::Url;
2153 /// # use url::ParseError;
2155 /// # fn run() -> Result<(), ParseError> {
2156 /// let mut url = Url::parse("https://example.net")?;
2157 /// let result = url.set_scheme("http");
2158 /// assert_eq!(url.as_str(), "http://example.net/");
2164 /// Change the URL’s scheme from `foo` to `bar`:
2167 /// use url::Url;
2168 /// # use url::ParseError;
2170 /// # fn run() -> Result<(), ParseError> {
2171 /// let mut url = Url::parse("foo://example.net")?;
2172 /// let result = url.set_scheme("bar");
2173 /// assert_eq!(url.as_str(), "bar://example.net");
2180 /// Cannot change URL’s scheme from `https` to `foõ`:
2183 /// use url::Url;
2184 /// # use url::ParseError;
2186 /// # fn run() -> Result<(), ParseError> {
2187 /// let mut url = Url::parse("https://example.net")?;
2188 /// let result = url.set_scheme("foõ");
2189 /// assert_eq!(url.as_str(), "https://example.net/");
2196 /// Cannot change URL’s scheme from `mailto` (cannot-be-a-base) to `https`:
2199 /// use url::Url;
2200 /// # use url::ParseError;
2202 /// # fn run() -> Result<(), ParseError> {
2203 /// let mut url = Url::parse("mailto:rms@example.net")?;
2204 /// let result = url.set_scheme("https");
2205 /// assert_eq!(url.as_str(), "mailto:rms@example.net");
2211 /// Cannot change the URL’s scheme from `foo` to `https`:
2214 /// use url::Url;
2215 /// # use url::ParseError;
2217 /// # fn run() -> Result<(), ParseError> {
2218 /// let mut url = Url::parse("foo://example.net")?;
2219 /// let result = url.set_scheme("https");
2220 /// assert_eq!(url.as_str(), "foo://example.net");
2226 /// Cannot change the URL’s scheme from `http` to `foo`:
2229 /// use url::Url;
2230 /// # use url::ParseError;
2232 /// # fn run() -> Result<(), ParseError> {
2233 /// let mut url = Url::parse("http://example.net")?;
2234 /// let result = url.set_scheme("foo");
2235 /// assert_eq!(url.as_str(), "http://example.net/");
2242 pub fn set_scheme(&mut self, scheme: &str) -> Result<(), ()> { in set_scheme()
2247 // If url’s scheme is a special scheme and buffer is not a special scheme, then return. in set_scheme()
2249 // If url’s scheme is not a special scheme and buffer is a special scheme, then return. in set_scheme()
2251 … // If url includes credentials or has a non-null port, and buffer is "file", then return. in set_scheme()
2252 // If url’s scheme is "file" and its host is an empty host or null, then return. in set_scheme()
2264 *index -= old_scheme_end; in set_scheme()
2293 /// Convert a file name as `std::path::Path` into an URL in the `file` scheme.
2300 /// On Unix-like platforms:
2304 /// use url::Url;
2306 /// # fn run() -> Result<(), ()> {
2307 /// let url = Url::from_file_path("/tmp/foo.txt")?;
2308 /// assert_eq!(url.as_str(), "file:///tmp/foo.txt");
2310 /// let url = Url::from_file_path("../foo.txt");
2311 /// assert!(url.is_err());
2313 /// let url = Url::from_file_path("https://google.com/");
2314 /// assert!(url.is_err());
2322 pub fn from_file_path<P: AsRef<Path>>(path: P) -> Result<Url, ()> { in from_file_path() argument
2326 Ok(Url { in from_file_path()
2340 /// Convert a directory name as `std::path::Path` into an URL in the `file` scheme.
2345 /// Compared to `from_file_path`, this ensure that URL’s the path has a trailing slash
2346 /// so that the entire path is considered when using this URL as a base URL.
2350 /// * `"index.html"` parsed with `Url::from_directory_path(Path::new("/var/www"))`
2351 /// as the base URL is `file:///var/www/index.html`
2352 /// * `"index.html"` parsed with `Url::from_file_path(Path::new("/var/www"))`
2353 /// as the base URL is `file:///var/index.html`, which might not be what was intended.
2359 pub fn from_directory_path<P: AsRef<Path>>(path: P) -> Result<Url, ()> { in from_directory_path() argument
2360 let mut url = Url::from_file_path(path)?; in from_directory_path() localVariable
2361 if !url.serialization.ends_with('/') { in from_directory_path()
2362 url.serialization.push('/') in from_directory_path()
2364 Ok(url) in from_directory_path()
2367 /// Serialize with Serde using the internal representation of the `Url` struct.
2369 /// The corresponding `deserialize_internal` method sacrifices some invariant-checking
2375 pub fn serialize_internal<S>(&self, serializer: S) -> Result<S::Ok, S::Error> in serialize_internal()
2382 let Url { in serialize_internal() localVariable
2409 /// Serialize with Serde using the internal representation of the `Url` struct.
2411 /// The corresponding `deserialize_internal` method sacrifices some invariant-checking
2417 pub fn deserialize_internal<'de, D>(deserializer: D) -> Result<Self, D::Error> in deserialize_internal()
2434 let url = Url { in deserialize_internal() localVariable
2447 url.check_invariants().map_err(|reason| { in deserialize_internal()
2452 Ok(url) in deserialize_internal()
2455 /// Assuming the URL is in the `file` scheme or similar,
2458 /// **Note:** This does not actually check the URL’s `scheme`,
2460 /// It is the user’s responsibility to check the URL’s scheme before calling this.
2463 /// # use url::Url;
2464 /// # let url = Url::parse("file:///etc/passwd").unwrap();
2465 /// let path = url.to_file_path();
2469 /// `file:` URLs may have a non-local host),
2471 /// (That is, if the percent-decoded path contains a NUL byte or,
2472 /// for a Windows path, is not UTF-8.)
2476 pub fn to_file_path(&self) -> Result<PathBuf, ()> { in to_file_path()
2494 fn slice<R>(&self, range: R) -> &str in slice()
2502 fn byte_at(&self, i: u32) -> u8 { in byte_at()
2507 /// Parse a string as an URL, without a base URL or encoding override.
2508 impl str::FromStr for Url { implementation
2512 fn from_str(input: &str) -> Result<Url, crate::ParseError> { in from_str() argument
2513 Url::parse(input) in from_str()
2517 impl<'a> TryFrom<&'a str> for Url { implementation
2520 fn try_from(s: &'a str) -> Result<Self, Self::Error> { in try_from()
2521 Url::parse(s) in try_from()
2525 /// Display the serialization of this URL.
2526 impl fmt::Display for Url { implementation
2528 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { in fmt()
2534 impl From<Url> for String {
2535 fn from(value: Url) -> String { in from()
2540 /// Debug the serialization of this URL.
2541 impl fmt::Debug for Url { implementation
2543 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { in fmt()
2545 .debug_struct("Url") in fmt()
2560 impl Eq for Url {} implementation
2563 impl PartialEq for Url { implementation
2565 fn eq(&self, other: &Self) -> bool { in eq()
2571 impl Ord for Url { implementation
2573 fn cmp(&self, other: &Self) -> cmp::Ordering { in cmp()
2579 impl PartialOrd for Url { implementation
2581 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { in partial_cmp()
2587 impl hash::Hash for Url { implementation
2597 /// Return the serialization of this URL.
2598 impl AsRef<str> for Url { implementation
2600 fn as_ref(&self) -> &str { in as_ref()
2606 fn slice_of<'a>(&self, s: &'a str) -> &'a str; in slice_of()
2611 fn slice_of<'a>(&self, s: &'a str) -> &'a str { in slice_of()
2618 fn slice_of<'a>(&self, s: &'a str) -> &'a str { in slice_of()
2625 fn slice_of<'a>(&self, s: &'a str) -> &'a str { in slice_of()
2630 /// Serializes this URL into a `serde` stream.
2634 impl serde::Serialize for Url { implementation
2635 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> in serialize()
2643 /// Deserializes this URL from a `serde` stream.
2647 impl<'de> serde::Deserialize<'de> for Url { implementation
2648 fn deserialize<D>(deserializer: D) -> Result<Url, D::Error> in deserialize() argument
2657 type Value = Url; in deserialize()
2659 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { in deserialize()
2660 formatter.write_str("a string representing an URL") in deserialize()
2663 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> in deserialize()
2667 Url::parse(s).map_err(|err| { in deserialize()
2682 ) -> Result<(u32, HostInternal), ()> { in path_to_file_url_segments()
2702 // An URL’s path must not be empty. in path_to_file_url_segments()
2712 ) -> Result<(u32, HostInternal), ()> { in path_to_file_url_segments()
2716 // Build this unconditionally to alleviate https://github.com/servo/rust-url/issues/102
2721 ) -> Result<(u32, HostInternal), ()> { in path_to_file_url_segments_windows()
2742 let host = Host::parse(server.to_str().ok_or(())?).map_err(|_| ())?; in path_to_file_url_segments_windows()
2762 // FIXME: somehow work with non-unicode? in path_to_file_url_segments_windows()
2784 ) -> Result<PathBuf, ()> { in file_url_segments_to_pathbuf()
2808 && matches!(bytes[bytes.len() - 2], b'a'..=b'z' | b'A'..=b'Z') in file_url_segments_to_pathbuf()
2809 && matches!(bytes[bytes.len() - 1], b':' | b'|') in file_url_segments_to_pathbuf()
2829 ) -> Result<PathBuf, ()> { in file_url_segments_to_pathbuf()
2833 // Build this unconditionally to alleviate https://github.com/servo/rust-url/issues/102
2838 ) -> Result<PathBuf, ()> { in file_url_segments_to_pathbuf_windows()
2872 // Currently non-unicode windows paths cannot be represented in file_url_segments_to_pathbuf_windows()
2886 /// Implementation detail of `Url::query_pairs_mut`. Typically not used directly.
2889 url: Option<&'a mut Url>, field
2893 // `as_mut_string` string here exposes the internal serialization of an `Url`,
2900 // `Url::query_pairs_mut` which is `Serializer<UrlQuery>`
2904 fn as_mut_string(&mut self) -> &mut String { in as_mut_string()
2905 &mut self.url.as_mut().unwrap().serialization in as_mut_string()
2908 fn finish(mut self) -> &'a mut Url { in finish() argument
2909 let url = self.url.take().unwrap(); in finish() localVariable
2910 url.restore_already_parsed_fragment(self.fragment.take()); in finish()
2911 url in finish()
2914 type Finished = &'a mut Url;
2919 if let Some(url) = self.url.take() { in drop()
2920 url.restore_already_parsed_fragment(self.fragment.take()) in drop()