pub struct Url { /* private fields */ }Expand description
Normalized URL reference.
The URL is stored in a single shared ByteString; accessors return
borrowed, percent-encoded components. Parsing is lenient and normalizes the
input the same way Python’s yarl does:
- leading and trailing whitespace and C0 controls, tabs and newlines are removed
- scheme and host are lowercased, non-ASCII hosts are punycode-encoded
- percent-encoding is normalized: invalid characters are encoded, escapes of unreserved characters are decoded, hex digits are uppercased
- dot segments are removed from absolute paths
- an empty path of
http,https,wsandwssURLs becomes/
The normalized URL always passes strict Url::validate.
use urly::Url;
let url: Url = "HTTPS://[email protected]:8443/a/./b/../c d?q=1#frag".parse().unwrap();
assert_eq!(url, "https://[email protected]:8443/a/c%20d?q=1#frag");
assert_eq!(url.scheme_str(), Some("https"));
assert_eq!(url.host(), Some("example.com"));
assert_eq!(url.port_u16(), Some(8443));
assert_eq!(url.path(), "/a/c%20d");
assert_eq!(url.path().decode(), "/a/c d");
assert_eq!(url.query().unwrap().get("q").unwrap(), "1");
assert_eq!(url.fragment().unwrap(), "frag");URLs are limited to 65535 bytes; operations that can’t return an error panic if the result exceeds the limit.
Implementations§
Source§impl Url
impl Url
Sourcepub fn from_parts(parts: Parts) -> Result<Url, InvalidUrlParts>
pub fn from_parts(parts: Parts) -> Result<Url, InvalidUrlParts>
Creates a URL from strictly validated parts.
use urly::{Parts, Url};
let url = Url::from_static("http://example.com/a?b#c");
let mut parts = url.into_parts();
assert_eq!(parts.path_and_query, "/a?b");
parts.fragment = None;
assert_eq!(Url::from_parts(parts).unwrap(), "http://example.com/a?b");
let parts = Parts { path_and_query: "a b".into(), ..Parts::default() };
assert!(Url::from_parts(parts).is_err());Source§impl Url
impl Url
Sourcepub fn parse<T: AsRef<str>>(src: T) -> Result<Url, InvalidUrl>
pub fn parse<T: AsRef<str>>(src: T) -> Result<Url, InvalidUrl>
Parses and normalizes an authority-form [userinfo@]host[:port], like
http::Uri does for a string without a scheme or a leading /.
The result is a network-path reference without a path. Use
Url::parse_ref to parse any URL reference, it treats such a string
as a relative path.
use urly::Url;
let url = Url::parse("Custom.Domain:8080").unwrap();
assert_eq!(url, "//custom.domain:8080");
assert_eq!(url.host(), Some("custom.domain"));
assert_eq!(url.port_u16(), Some(8080));
assert_eq!(url.path(), "");
assert!(Url::parse("custom.domain/path").is_err());
assert_eq!(Url::parse_ref("custom.domain").unwrap().host(), None);Sourcepub fn parse_ref<T: AsRef<str>>(src: T) -> Result<Url, InvalidUrl>
pub fn parse_ref<T: AsRef<str>>(src: T) -> Result<Url, InvalidUrl>
Parses and normalizes a URL reference.
Same as Url::try_from() and str::parse().
Sourcepub fn validate<T: AsRef<[u8]>>(src: T) -> Result<(), InvalidUrl>
pub fn validate<T: AsRef<[u8]>>(src: T) -> Result<(), InvalidUrl>
Strictly validates a URI reference according to RFC 3986.
Unlike parsing, validation does not normalize: whitespace, non-ASCII
characters and invalid escapes are errors. The error position is a byte
offset into src. Input that is not valid UTF-8 is rejected with
ErrorKind::InvalidChar at its first
non-ASCII byte.
use urly::{ErrorKind, Url};
assert!(Url::validate("https://example.com/a%20b?q#f").is_ok());
assert!(Url::validate(b"/path?q").is_ok());
let err = Url::validate("http://ex ample.com").unwrap_err();
assert_eq!(err.kind(), ErrorKind::InvalidChar(' '));
assert_eq!(err.position(), Some(9));
let err = Url::validate(b"/a\xff").unwrap_err();
assert_eq!(err.kind(), ErrorKind::InvalidChar(char::REPLACEMENT_CHARACTER));
assert_eq!(err.position(), Some(2));Sourcepub fn from_static(src: &'static str) -> Url
pub fn from_static(src: &'static str) -> Url
Converts a static string to a URL. The string is not copied if it is already normalized.
§Panics
Panics if the URL is not valid.
Converts a Bytes, String, Vec<u8> or any other
byte buffer to a URL, reusing the buffer if possible.
Sourcepub fn as_byte_string(&self) -> &ByteString
pub fn as_byte_string(&self) -> &ByteString
Returns the underlying buffer.
Sourcepub fn scheme_str(&self) -> Option<&str>
pub fn scheme_str(&self) -> Option<&str>
Returns the scheme as a string, if present.
Returns the authority, if present.
Sourcepub fn host(&self) -> Option<&str>
pub fn host(&self) -> Option<&str>
Returns the host, if present and not empty. IPv6 addresses include the brackets, non-ASCII domains are punycode-encoded.
Sourcepub fn host_parsed(&self) -> Option<Host<'_>>
pub fn host_parsed(&self) -> Option<Host<'_>>
Returns the parsed host, if present and not empty.
use std::net::Ipv4Addr;
use urly::{Host, Url};
let url = Url::from_static("http://127.0.0.1/");
assert_eq!(url.host_parsed(), Some(Host::Ipv4(Ipv4Addr::LOCALHOST)));
let url = Url::from_static("http://münchen.de/");
assert_eq!(url.host(), Some("xn--mnchen-3ya.de"));
assert_eq!(url.host_parsed().unwrap().to_unicode(), "münchen.de");Sourcepub fn port_or_known_default(&self) -> Option<u16>
pub fn port_or_known_default(&self) -> Option<u16>
Returns the explicit port, or the default port of the scheme.
Sourcepub fn path(&self) -> &Path
pub fn path(&self) -> &Path
Returns the percent-encoded path.
A path starting with // in a URL without authority is serialized with a
/. prefix, which is not part of the path.
use urly::Url;
let url = Url::from_static("/.//a?q");
assert_eq!(url.path(), "//a");
assert_eq!(url.path_and_query(), "//a?q");Sourcepub fn path_and_query(&self) -> &PathAndQuery
pub fn path_and_query(&self) -> &PathAndQuery
Returns the path and query.
Sourcepub fn is_absolute(&self) -> bool
pub fn is_absolute(&self) -> bool
Returns true if the URL has a scheme.
Sourcepub fn is_default_port(&self) -> bool
pub fn is_default_port(&self) -> bool
Returns true if the port is absent or is the default port of the scheme.
Sourcepub fn origin(&self) -> Option<Url>
pub fn origin(&self) -> Option<Url>
Returns the origin: scheme, host and port.
use urly::Url;
let url = Url::from_static("https://user:[email protected]:8443/a?b#c");
assert_eq!(url.origin().unwrap(), "https://example.com:8443/");
assert!(Url::from_static("/a").origin().is_none());Sourcepub fn relative(&self) -> Url
pub fn relative(&self) -> Url
Returns the relative part of the URL: path, query and fragment.
use urly::Url;
let url = Url::from_static("https://example.com/a?b#c");
assert_eq!(url.relative(), "/a?b#c");Sourcepub fn parent(&self) -> Url
pub fn parent(&self) -> Url
Returns the URL with the last path segment removed, without query and fragment.
use urly::Url;
assert_eq!(Url::from_static("http://h/a/b?q").parent(), "http://h/a");
assert_eq!(Url::from_static("http://h/a/b/").parent(), "http://h/a");
assert_eq!(Url::from_static("http://h/a").parent(), "http://h/");
assert_eq!(Url::from_static("http://h/").parent(), "http://h/");Sourcepub fn push_segments<I, S>(&self, segments: I) -> Url
pub fn push_segments<I, S>(&self, segments: I) -> Url
Appends literal path segments, without query and fragment.
Segments are percent-encoded; / is kept and a leading / is ignored.
The same operation is available as the / operator.
use urly::Url;
let url = Url::from_static("http://h/api?q");
assert_eq!(url.push_segments(["v1", "a b"]), "http://h/api/v1/a%20b");
assert_eq!(&url / "users/" / "1", "http://h/api/users/1");Sourcepub fn join(&self, reference: &str) -> Result<Url, InvalidUrl>
pub fn join(&self, reference: &str) -> Result<Url, InvalidUrl>
Resolves a reference against this URL, RFC 3986 section 5.2.
use urly::Url;
let base = Url::from_static("http://a/b/c/d;p?q");
assert_eq!(base.join("../g").unwrap(), "http://a/b/g");
assert_eq!(base.join("//g/x").unwrap(), "http://g/x");
assert_eq!(base.join("?y").unwrap(), "http://a/b/c/d;p?y");Sourcepub fn join_url(&self, r: &Url) -> Url
pub fn join_url(&self, r: &Url) -> Url
Resolves a parsed reference against this URL, RFC 3986 section 5.2.2.
The + and += operators are equivalent.
use urly::Url;
let base = Url::from_static("http://a/b/c/d;p?q");
let r = Url::from_static("../g");
assert_eq!(base.join_url(&r), "http://a/b/g");
assert_eq!(&base + &r, "http://a/b/g");
let mut url = base.clone();
url += r;
assert_eq!(url, "http://a/b/g");Sourcepub fn set_scheme(&mut self, scheme: &str) -> Result<(), InvalidUrl>
pub fn set_scheme(&mut self, scheme: &str) -> Result<(), InvalidUrl>
Sets the scheme.
Sets or removes the raw authority: [userinfo "@"] host [":" port].
Sourcepub fn set_userinfo(
&mut self,
username: Option<&str>,
password: Option<&str>,
) -> Result<(), InvalidUrl>
pub fn set_userinfo( &mut self, username: Option<&str>, password: Option<&str>, ) -> Result<(), InvalidUrl>
Sets or removes the literal user name and password.
use urly::Url;
let mut url = Url::from_static("http://example.com/");
url.set_userinfo(Some("us@r"), Some("p:w")).unwrap();
assert_eq!(url, "http://us%40r:p%[email protected]/");
assert_eq!(url.password().unwrap(), "p:w");Sourcepub fn set_host(&mut self, host: &str) -> Result<(), InvalidUrl>
pub fn set_host(&mut self, host: &str) -> Result<(), InvalidUrl>
Sets the host. Escapes are decoded, non-ASCII domains are punycode-encoded, IPv6 addresses may be given without brackets.
An authority is added if the URL doesn’t have one.
use urly::Url;
let mut url = Url::from_static("http://[email protected]:8080/a");
url.set_host("::1").unwrap();
assert_eq!(url, "http://user@[::1]:8080/a");
url.set_host("Bücher.example").unwrap();
assert_eq!(url, "http://[email protected]:8080/a");Sourcepub fn set_port(&mut self, port: Option<u16>) -> Result<(), InvalidUrl>
pub fn set_port(&mut self, port: Option<u16>) -> Result<(), InvalidUrl>
Sets or removes the port.
Sourcepub fn set_path(&mut self, path: &str)
pub fn set_path(&mut self, path: &str)
Sets the percent-encoded path, keeping query and fragment.
Invalid characters are encoded and dot segments are removed.
use urly::Url;
let mut url = Url::from_static("http://h/a?q");
url.set_path("/b/../c d");
assert_eq!(url, "http://h/c%20d?q");Sourcepub fn set_file_name(&mut self, name: &str) -> Result<(), InvalidUrl>
pub fn set_file_name(&mut self, name: &str) -> Result<(), InvalidUrl>
Replaces the last path segment with a literal file name.
use urly::Url;
let mut url = Url::from_static("http://h/a/b.txt?q");
url.set_file_name("c d.html").unwrap();
assert_eq!(url, "http://h/a/c%20d.html?q");Sourcepub fn set_extension(&mut self, extension: &str) -> Result<(), InvalidUrl>
pub fn set_extension(&mut self, extension: &str) -> Result<(), InvalidUrl>
Replaces the extension of the file name; an empty extension removes it.
use urly::Url;
let mut url = Url::from_static("http://h/a/b.txt");
url.set_extension("tar.gz").unwrap();
assert_eq!(url, "http://h/a/b.tar.gz");
url.set_extension("").unwrap();
assert_eq!(url, "http://h/a/b.tar");Sourcepub fn set_query(&mut self, query: Option<&str>)
pub fn set_query(&mut self, query: Option<&str>)
Sets or removes the percent-encoded query.
use urly::Url;
let mut url = Url::from_static("http://h/#f");
url.set_query(Some("a=b c&d"));
assert_eq!(url, "http://h/?a=b+c&d#f");Sourcepub fn set_query_pairs<I, K, V>(&mut self, pairs: I)
pub fn set_query_pairs<I, K, V>(&mut self, pairs: I)
Replaces the query with literal key-value pairs. Empty pairs remove the query.
use urly::Url;
let mut url = Url::from_static("http://h/?old");
url.set_query_pairs([("a", "1 2"), ("b&", "=")]);
assert_eq!(url, "http://h/?a=1+2&b%26=%3D");Sourcepub fn extend_query_pairs<I, K, V>(&mut self, pairs: I)
pub fn extend_query_pairs<I, K, V>(&mut self, pairs: I)
Appends literal key-value pairs to the query.
Sourcepub fn update_query_pairs<I, K, V>(&mut self, pairs: I)
pub fn update_query_pairs<I, K, V>(&mut self, pairs: I)
Replaces all values of the given keys, appending the new pairs.
use urly::Url;
let mut url = Url::from_static("http://h/?a=1&b=2&a=3");
url.update_query_pairs([("a", "4")]);
assert_eq!(url, "http://h/?b=2&a=4");Sourcepub fn remove_query_params<I, K>(&mut self, keys: I)
pub fn remove_query_params<I, K>(&mut self, keys: I)
Removes all pairs with the given keys from the query.
use urly::Url;
let mut url = Url::from_static("http://h/?a=1&b=2&a=3");
url.remove_query_params(["a"]);
assert_eq!(url, "http://h/?b=2");
url.remove_query_params(["b"]);
assert_eq!(url, "http://h/");Sourcepub fn set_fragment(&mut self, fragment: Option<&str>)
pub fn set_fragment(&mut self, fragment: Option<&str>)
Sets or removes the percent-encoded fragment.
Sourcepub fn into_parts(self) -> Parts
pub fn into_parts(self) -> Parts
Splits the URL into its parts.
Sourcepub fn into_byte_string(self) -> ByteString
pub fn into_byte_string(self) -> ByteString
Converts the URL into its buffer.
Trait Implementations§
Source§impl<U: Borrow<Url>> AddAssign<U> for Url
impl<U: Borrow<Url>> AddAssign<U> for Url
Source§fn add_assign(&mut self, reference: U)
fn add_assign(&mut self, reference: U)
+= operation. Read moreimpl Eq for Url
Source§impl From<Url> for ByteString
impl From<Url> for ByteString
Source§fn from(url: Url) -> ByteString
fn from(url: Url) -> ByteString
Source§impl Ord for Url
impl Ord for Url
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl PartialOrd for Url
impl PartialOrd for Url
Source§impl TryFrom<&ByteString> for Url
impl TryFrom<&ByteString> for Url
Source§type Error = InvalidUrl
type Error = InvalidUrl
Source§fn try_from(s: &ByteString) -> Result<Url, InvalidUrl>
fn try_from(s: &ByteString) -> Result<Url, InvalidUrl>
Source§impl TryFrom<&Uri> for Url
impl TryFrom<&Uri> for Url
Source§type Error = InvalidUrl
type Error = InvalidUrl
Source§impl TryFrom<&Url> for Uri
The fragment is removed, Uri doesn’t support it. A network-path
reference converts to authority-form, it fails if it has a path or
query.
impl TryFrom<&Url> for Uri
The fragment is removed, Uri doesn’t support it. A network-path
reference converts to authority-form, it fails if it has a path or
query.