rust-url

repository·main·Indexed 23 days ago

https://github.com/servo/rust-url

A Rust implementation of the WHATWG URL Standard for robust URL parsing and manipulation. The project includes the data-url crate for processing data: URLs according to the Fetch Standard, the idna crate for hostname preparation and user-interface display, and support for debugger visualizers (Natvis and Pretty printers) via the #[debugger_visualizer] attribute.

Tokens
14.1K
Snippets
43
Records
87
Agent score
81%

What's inside rust-url

  1. Use alternative Unicode back ends with `idna`

    main

    By default, idna uses ICU4X as its Unicode back end.

    To optimize for different trade-offs (correctness, run-time performance, binary size, compile time, or MSRV), you can opt into a different Unicode back end by following the instructions in the idna_adapter crate documentation.

  2. Configure alternative Unicode back ends for IDNA

    main

    The url crate depends on the idna crate. By default, idna uses ICU4X as its Unicode back end.

    If you need to change the Unicode back end to optimize for different tradeoffs—such as correctness, run-time performance, binary size, compile time, or Minimum Supported Rust Version (MSRV)—you must use the idna_adapter crate. Refer to the idna_adapter documentation for specific configuration instructions.

  3. Migrate from url 0.x to 1.x: Path handling

    main

    The API for interacting with URL paths has changed significantly in url 1.x:

    • path(): Now returns &str instead of Option<&[String]>. It returns the full path string (e.g., "/foo/bar").
    • path_segments(): Use this if you need the old behavior of iterating over segments. It returns Option<str::Split<char>>.
    • path_segments_mut(): Replaces path_mut() for modifying the path segments of a Url.
    // Before upgrading (0.x)
    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 (1.x)
    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"]));
  4. Migrate from url 0.x to 1.x: URL Parsing and Joining

    main

    The UrlParser struct has been removed. Use the methods directly on Url instances:

    • Parsing: Use Url::parse().
    • Joining/Resolving: Use Url::join() instead of UrlParser::parse().

    If you need to parse a raw path string without a base URL (previously url::parse_path()), use a dummy base URL with join() as a workaround.

    // Before upgrading (0.x)
    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 (1.x)
    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");
  5. Migrate from url 0.x to 1.x: Query and Form Encoding

    main

    Query string and form encoding APIs have been refactored:

    • query_pairs_mut(): Replaces set_query_from_pairs(). It allows you to modify query pairs via a mutable interface (e.g., .clear().extend_pairs(...)).
    • url::form_urlencoded::Serializer: Replaces the old url::form_urlencoded::serialize() function. You must now create a Serializer with a String, call extend_pairs(), and then finish().
    // Before upgrading (0.x)
    let form = url::form_urlencoded::serialize(form.iter().map(|(k, v)| {
        (&k[..], &v[..])
    }));
    
    // After upgrading (1.x)
    let form = url::form_urlencoded::Serializer::new(String::new()).extend_pairs(
        form.iter().map(|(k, v)| { (&k[..], &v[..]) })
    ).finish();
  6. Migrate from url 0.x to 1.x: Domain and Host handling

    main

    Methods for managing the host/domain of a Url have been updated:

    • set_host() and set_ip_host(): Replace the old domain_mut() method.
    • host(): Now returns Option<Host<&str>> instead of Option<&Host>.
    • host_str(): Replaces serialize_host() (which returned Option<String>) and returns Option<&str>.
  7. Display hostnames to users using `uts46::Uts46::to_user_interface`

    main

    When you need to display a hostname to a user in a UI, use uts46::Uts46::to_user_interface.

    Avoid using the general ToUnicode operation for direct application usage, as it is rarely the appropriate operation for user-facing displays.

  8. Migrate from url 0.x to 1.x: Url field access and mutation

    main

    In url 1.x, the fields of the Url struct are private to maintain invariants. You must use getter and setter methods instead of direct field access or assignment.

    • Accessing fields: Use getter methods like url.scheme() instead of url.scheme.
    • Modifying fields: Use setter methods like url.set_scheme("https").unwrap() instead of direct assignment (e.g., url.scheme = "https".to_string()). Note that some setters return a Result that must be handled.
  9. Prepare hostnames for protocols using `domain_to_ascii_cow`

    main

    If you need to prepare a hostname for use in network protocols, use the domain_to_ascii_cow function. For standard WHATWG URL compliance, pass AsciiDenyList::URL as the second argument.

    Important: This function rejects IPv6 addresses. You must manually check if the input starts with b'[' and handle it as an IPv6 address before calling this function.

  10. Upgrade from url 1.x to 2.1+

    main

    When upgrading the url crate from version 1.x to 2.1 or higher, note the following breaking changes:

    Minimum Supported Rust Version (MSRV)

    The minimum supported Rust version is now v1.33.0. Ensure your project can support this version.

    Replacing std::net::ToSocketAddrs with socket_addrs

    Url no longer implements std::net::ToSocketAddrs. You must explicitly call the socket_addrs method to convert a Url into a type compatible with TcpStream::connect or similar networking functions.

    Note: While v2.0 removed ToSocketAddrs without a replacement, the socket_addrs method was introduced in v2.1.

    Serde Integration

    url_serde is no longer required for using Url with Serde 1.x. Remove url_serde from your dependencies and enable the serde feature directly on the url crate.

    Dependency Changes for idna and percent_encoding

    The url crate no longer re-exports the idna and percent_encoding crates. You must add these as direct dependencies in your Cargo.toml and import them directly.

    # Cargo.toml
    [dependencies]
    url = { version = "2.0", features = ["serde"] }
  11. Migrate from url 0.x to 1.x: percent-encoding changes

    main

    The percent-encoding crate has several breaking changes:

    • percent_decode(): Now returns an iterator of decoded u8 bytes instead of a Vec<u8>. To get a Vec<u8>, use .into().to_owned() or .collect().
    • percent_decode_to(): Removed. Use percent_decode() and then collect() or extend().
    • EncodeSet: Now implemented as a trait.
      • SIMPLE_ENCODE_SET, QUERY_ENCODE_SET, DEFAULT_ENCODE_SET, and USERINFO_ENCODE_SET remain.
      • USERNAME_ENCODE_SET and PASSWORD_ENCODE_SET are removed; use USERINFO_ENCODE_SET instead.
      • PATH_SEGMENT_ENCODE_SET is a new addition for '/'-separated path segments.