Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 1 addition & 45 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ authors = [
"LongYinan <github@lyn.one>",
"Boshen <boshenc@gmail.com>"
]
version = "3.2.6"
version = "3.3.0"
edition = "2024"
description = "Fast WHATWG Compliant URL parser"
documentation = "https://docs.rs/ada-url"
Expand All @@ -32,7 +32,6 @@ serde = ["dep:serde", "std"]
std = []

[dependencies]
derive_more = { version = "1", features = ["full"] }
serde = { version = "1", optional = true, features = ["derive"] }

[dev-dependencies]
Expand Down
27 changes: 23 additions & 4 deletions deps/ada.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* auto-generated on 2025-07-16 22:15:14 -0400. Do not edit! */
/* auto-generated on 2025-09-23 12:57:35 -0400. Do not edit! */
/* begin file src/ada.cpp */
#include "ada.h"
/* begin file src/checkers.cpp */
Expand Down Expand Up @@ -9511,12 +9511,14 @@ bool is_label_valid(const std::u32string_view label) {
for (size_t i = 0; i <= last_non_nsm_char; i++) {
const direction d = find_direction(label[i]);

// NOLINTBEGIN(bugprone-assignment-in-if-condition)
// In an RTL label, if an EN is present, no AN may be present, and vice
// versa.
if ((d == direction::EN && ((has_en = true) && has_an)) ||
(d == direction::AN && ((has_an = true) && has_en))) {
return false;
}
// NOLINTEND(bugprone-assignment-in-if-condition)

if (!(d == direction::R || d == direction::AL || d == direction::AN ||
d == direction::EN || d == direction::ES || d == direction::CS ||
Expand Down Expand Up @@ -10908,6 +10910,7 @@ bool percent_encode(const std::string_view input, const uint8_t character_set[],
}
ada_log("percent_encode appending ", std::distance(input.begin(), pointer),
" bytes");
// NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
out.append(input.data(), std::distance(input.begin(), pointer));
ada_log("percent_encode processing ", std::distance(pointer, input.end()),
" bytes");
Expand Down Expand Up @@ -10942,6 +10945,7 @@ bool to_ascii(std::optional<std::string>& out, const std::string_view plain,
std::string percent_encode(const std::string_view input,
const uint8_t character_set[], size_t index) {
std::string out;
// NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
out.append(input.data(), index);
auto pointer = input.begin() + index;
for (; pointer != input.end(); pointer++) {
Expand Down Expand Up @@ -12008,6 +12012,7 @@ ada_warn_unused std::string to_string(ada::state state) {

#include <numeric>
#include <algorithm>
#include <iterator>
#include <ranges>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -12570,6 +12575,7 @@ ada_really_inline void url::parse_path(std::string_view input) {
if (has_search()) {
answer.append(",\n");
answer.append("\t\"query\":\"");
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
helpers::encode_json(query.value(), back);
answer.append("\"");
}
Expand Down Expand Up @@ -13316,6 +13322,7 @@ result_type parse_url_impl(std::string_view user_input,

// If c is U+002F (/), then set state to relative slash state.
if ((input_position != input_size) &&
// NOLINTNEXTLINE(bugprone-branch-clone)
(url_data[input_position] == '/')) {
ada_log(
"RELATIVE_SCHEME if c is U+002F (/), then set state to relative "
Expand Down Expand Up @@ -13848,6 +13855,7 @@ template url_aggregator parse_url<url_aggregator>(
/* end file src/parser.cpp */
/* begin file src/url_components.cpp */

#include <iterator>
#include <string>

namespace ada {
Expand Down Expand Up @@ -13897,6 +13905,7 @@ namespace ada {
/* end file src/url_components.cpp */
/* begin file src/url_aggregator.cpp */

#include <iterator>
#include <ranges>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -15832,7 +15841,11 @@ tl::expected<std::string, errors> url_pattern_init::process_search(
if (value.starts_with("?")) {
value.remove_prefix(1);
}
ADA_ASSERT_TRUE(!value.starts_with("?"));
// We cannot assert that the value is no longer starting with a single
// question mark because technically it can start. The question is whether or
// not we should remove the first question mark. Ref:
// https://github.com/ada-url/ada/pull/992 The spec is not clear on this.

// If type is "pattern" then return strippedValue.
if (type == process_type::pattern) {
return std::string(value);
Expand Down Expand Up @@ -16273,7 +16286,10 @@ tl::expected<std::string, errors> canonicalize_search(std::string_view input) {
url->set_search(input);
if (url->has_search()) {
const auto search = url->get_search();
return std::string(search.substr(1));
if (!search.empty()) {
return std::string(search.substr(1));
}
return "";
}
return tl::unexpected(errors::type_error);
}
Expand All @@ -16293,7 +16309,10 @@ tl::expected<std::string, errors> canonicalize_hash(std::string_view input) {
// Return dummyURL's fragment.
if (url->has_hash()) {
const auto hash = url->get_hash();
return std::string(hash.substr(1));
if (!hash.empty()) {
return std::string(hash.substr(1));
}
return "";
}
return tl::unexpected(errors::type_error);
}
Expand Down
11 changes: 6 additions & 5 deletions deps/ada.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* auto-generated on 2025-07-16 22:15:14 -0400. Do not edit! */
/* auto-generated on 2025-09-23 12:57:35 -0400. Do not edit! */
/* begin file include/ada.h */
/**
* @file ada.h
Expand Down Expand Up @@ -947,7 +947,7 @@ constexpr uint8_t WWW_FORM_URLENCODED_PERCENT_ENCODE[32] = {
// 50 51 52 53 54 55 56 57
0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
// 58 59 5A 5B 5C 5D 5E 5F
0x00 | 0x00 | 0x00 | 0x08 | 0x00 | 0x20 | 0x40 | 0x00,
0x00 | 0x00 | 0x00 | 0x08 | 0x10 | 0x20 | 0x40 | 0x00,
// 60 61 62 63 64 65 66 67
0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
// 68 69 6A 6B 6C 6D 6E 6F
Expand Down Expand Up @@ -6641,6 +6641,7 @@ inline std::ostream &operator<<(std::ostream &out, const ada::url &u) {
out.protocol_end = uint32_t(get_protocol().size());

// Trailing index is always the next character of the current one.
// NOLINTNEXTLINE(clang-analyzer-deadcode.DeadStores)
size_t running_index = out.protocol_end;

if (host.has_value()) {
Expand Down Expand Up @@ -10514,14 +10515,14 @@ constructor_string_parser<regex_provider>::parse(std::string_view input) {
#ifndef ADA_ADA_VERSION_H
#define ADA_ADA_VERSION_H

#define ADA_VERSION "3.2.6"
#define ADA_VERSION "3.3.0"

namespace ada {

enum {
ADA_VERSION_MAJOR = 3,
ADA_VERSION_MINOR = 2,
ADA_VERSION_REVISION = 6,
ADA_VERSION_MINOR = 3,
ADA_VERSION_REVISION = 0,
};

} // namespace ada
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "1.86.0"
channel = "1.90.0"
profile = "default"
15 changes: 10 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,23 @@ extern crate std;
use std::string::String;

use core::{borrow, ffi::c_uint, fmt, hash, ops};
use derive_more::Display;

/// Error type of [`Url::parse`].
#[derive(Debug, Display, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(derive_more::Error))] // error still requires std: https://github.com/rust-lang/rust/issues/103765
#[display(bound(Input: core::fmt::Debug))]
#[display("Invalid url: {input:?}")]
#[derive(Debug, PartialEq, Eq)]
pub struct ParseUrlError<Input> {
/// The invalid input that caused the error.
pub input: Input,
}

impl<Input: core::fmt::Debug> fmt::Display for ParseUrlError<Input> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Invalid url: {:?}", self.input)
}
}

#[cfg(feature = "std")] // error still requires std: https://github.com/rust-lang/rust/issues/103765
impl<Input: core::fmt::Debug> std::error::Error for ParseUrlError<Input> {}

/// Defines the type of the host.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum HostType {
Expand Down
8 changes: 4 additions & 4 deletions src/url_search_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ impl UrlSearchParams {
/// let pairs = params.get_all("a");
/// assert_eq!(pairs.len(), 2);
/// ```
pub fn get_all(&self, key: &str) -> UrlSearchParamsEntry {
pub fn get_all(&self, key: &str) -> UrlSearchParamsEntry<'_> {
unsafe {
let strings = ffi::ada_search_params_get_all(self.0, key.as_ptr().cast(), key.len());
let size = ffi::ada_strings_size(strings);
Expand All @@ -198,7 +198,7 @@ impl UrlSearchParams {
/// .expect("String should have been able to be parsed into an UrlSearchParams.");
/// let mut keys = params.keys();
/// assert!(keys.next().is_some());
pub fn keys(&self) -> UrlSearchParamsKeyIterator {
pub fn keys(&self) -> UrlSearchParamsKeyIterator<'_> {
let iterator = unsafe { ffi::ada_search_params_get_keys(self.0) };
UrlSearchParamsKeyIterator::new(iterator)
}
Expand All @@ -211,7 +211,7 @@ impl UrlSearchParams {
/// .expect("String should have been able to be parsed into an UrlSearchParams.");
/// let mut values = params.values();
/// assert!(values.next().is_some());
pub fn values(&self) -> UrlSearchParamsValueIterator {
pub fn values(&self) -> UrlSearchParamsValueIterator<'_> {
let iterator = unsafe { ffi::ada_search_params_get_values(self.0) };
UrlSearchParamsValueIterator::new(iterator)
}
Expand All @@ -225,7 +225,7 @@ impl UrlSearchParams {
/// let mut entries = params.entries();
/// assert_eq!(entries.next(), Some(("a", "1")));
/// ```
pub fn entries(&self) -> UrlSearchParamsEntryIterator {
pub fn entries(&self) -> UrlSearchParamsEntryIterator<'_> {
let iterator = unsafe { ffi::ada_search_params_get_entries(self.0) };
UrlSearchParamsEntryIterator::new(iterator)
}
Expand Down
Loading