Skip to content

Commit f8a1087

Browse files
authored
Merge branch 'main' into 198
2 parents 75d493e + 783c76b commit f8a1087

10 files changed

+77
-50
lines changed

Cargo.toml

+2-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ repository = "https://github.com/denoland/rust-urlpattern"
88
license = "MIT"
99

1010
[dependencies]
11-
derive_more = "0.99.16"
12-
url = "2.2.2"
13-
regex = "1.4.3"
11+
url = "2.4.1"
12+
regex = "1.10.5"
1413
serde = { version = "1.0.127", features = ["derive"] }
1514
unic-ucd-ident = { version = "0.9.0", features = ["id"] }
1615

src/component.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,13 @@ impl<R: RegExp> Component<R> {
6767
pub(crate) fn create_match_result(
6868
&self,
6969
input: String,
70-
exec_result: Vec<&str>,
70+
exec_result: Vec<Option<&str>>,
7171
) -> crate::UrlPatternComponentResult {
7272
let groups = self
7373
.group_name_list
7474
.clone()
7575
.into_iter()
76-
.zip(exec_result.into_iter().map(str::to_owned))
76+
.zip(exec_result.into_iter().map(|s| s.map(str::to_owned)))
7777
.collect();
7878
crate::UrlPatternComponentResult { input, groups }
7979
}

src/error.rs

+54-27
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,80 @@
1-
use derive_more::Display;
1+
use std::fmt;
22

33
use crate::tokenizer::TokenType;
44

55
/// A error occurring during URL pattern construction, or matching.
6-
#[derive(Display)]
6+
#[derive(Debug)]
77
pub enum Error {
8-
#[display(fmt = "a relative input without a base URL is not valid")]
98
BaseUrlRequired,
10-
11-
#[display(
12-
fmt = "specifying both an init object, and a separate base URL is not valid"
13-
)]
149
BaseUrlWithInit,
15-
16-
#[display(fmt = "tokenizer error: {_0} (at char {_1})")]
1710
Tokenizer(TokenizerError, usize),
18-
19-
#[display(fmt = "parser error: {_0}")]
2011
Parser(ParserError),
21-
2212
Url(url::ParseError),
23-
24-
#[display(fmt = "regexp error")]
2513
RegExp(()),
2614
}
2715

28-
impl std::error::Error for Error {}
29-
30-
impl std::fmt::Debug for Error {
31-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32-
std::fmt::Display::fmt(self, f)
16+
impl fmt::Display for Error {
17+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18+
match self {
19+
Error::BaseUrlRequired => {
20+
f.write_str("a relative input without a base URL is not valid")
21+
}
22+
Error::BaseUrlWithInit => f.write_str(
23+
"specifying both an init object, and a separate base URL is not valid",
24+
),
25+
Error::Tokenizer(err, pos) => {
26+
write!(f, "tokenizer error: {err} (at char {pos})")
27+
}
28+
Error::Parser(err) => write!(f, "parser error: {err}"),
29+
Error::Url(err) => err.fmt(f),
30+
Error::RegExp(_) => f.write_str("regexp error"),
31+
}
3332
}
3433
}
3534

36-
#[derive(Debug, Display)]
35+
impl std::error::Error for Error {}
36+
37+
#[derive(Debug)]
3738
pub enum TokenizerError {
38-
#[display(fmt = "incomplete escape code")]
3939
IncompleteEscapeCode,
40-
#[display(fmt = "invalid name; must be at least length 1")]
4140
InvalidName,
42-
#[display(fmt = "invalid regex: {_0}")]
4341
InvalidRegex(&'static str),
4442
}
4543

46-
#[derive(Debug, Display)]
44+
impl fmt::Display for TokenizerError {
45+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46+
match self {
47+
Self::IncompleteEscapeCode => f.write_str("incomplete escape code"),
48+
Self::InvalidName => {
49+
f.write_str("invalid name; must be at least length 1")
50+
}
51+
Self::InvalidRegex(err) => write!(f, "invalid regex: {err}"),
52+
}
53+
}
54+
}
55+
56+
impl std::error::Error for TokenizerError {}
57+
58+
#[derive(Debug)]
4759
pub enum ParserError {
48-
#[display(fmt = "expected token {_0}, found '{_2}' of type {_1}")]
4960
ExpectedToken(TokenType, TokenType, String),
50-
51-
#[display(fmt = "pattern contains duplicate name {_0}")]
5261
DuplicateName(String),
5362
}
63+
64+
impl fmt::Display for ParserError {
65+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66+
match self {
67+
Self::ExpectedToken(expected_ty, found_ty, found_val) => {
68+
write!(
69+
f,
70+
"expected token {expected_ty:?}, found '{found_val}' of type {found_ty:?}"
71+
)
72+
}
73+
Self::DuplicateName(name) => {
74+
write!(f, "pattern contains duplicate name {name}")
75+
}
76+
}
77+
}
78+
}
79+
80+
impl std::error::Error for ParserError {}

src/lib.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ fn is_absolute_pathname(
255255
/// // Match the pattern against a URL.
256256
/// let url = "https://example.com/users/123".parse().unwrap();
257257
/// let result = pattern.exec(UrlPatternMatchInput::Url(url)).unwrap().unwrap();
258-
/// assert_eq!(result.pathname.groups.get("id").unwrap(), "123");
258+
/// assert_eq!(result.pathname.groups.get("id").unwrap().as_ref().unwrap(), "123");
259259
///# }
260260
/// ```
261261
#[derive(Debug)]
@@ -549,7 +549,7 @@ pub struct UrlPatternComponentResult {
549549
/// The matched input for this component.
550550
pub input: String,
551551
/// The values for all named groups in the pattern.
552-
pub groups: std::collections::HashMap<String, String>,
552+
pub groups: std::collections::HashMap<String, Option<String>>,
553553
}
554554

555555
#[cfg(test)]
@@ -578,7 +578,7 @@ mod tests {
578578
#[derive(Debug, Deserialize)]
579579
struct ComponentResult {
580580
input: String,
581-
groups: HashMap<String, String>,
581+
groups: HashMap<String, Option<String>>,
582582
}
583583

584584
#[derive(Deserialize)]
@@ -631,7 +631,7 @@ mod tests {
631631
}
632632

633633
fn test_case(case: TestCase) {
634-
let input = case.pattern.get(0).cloned();
634+
let input = case.pattern.first().cloned();
635635
let mut base_url = case.pattern.get(1).map(|input| match input {
636636
StringOrInit::String(str) => str.clone(),
637637
StringOrInit::Init(_) => unreachable!(),
@@ -742,7 +742,7 @@ mod tests {
742742
assert_field!(search);
743743
assert_field!(hash);
744744

745-
let input = case.inputs.get(0).cloned();
745+
let input = case.inputs.first().cloned();
746746
let base_url = case.inputs.get(1).map(|input| match input {
747747
StringOrInit::String(str) => str.clone(),
748748
StringOrInit::Init(_) => unreachable!(),
@@ -840,7 +840,7 @@ mod tests {
840840
if !exactly_empty_components
841841
.contains(&stringify!($component).to_owned())
842842
{
843-
groups.insert("0".to_owned(), "".to_owned());
843+
groups.insert("0".to_owned(), Some("".to_owned()));
844844
}
845845
UrlPatternComponentResult {
846846
input: "".to_owned(),

src/matcher.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ impl<R: RegExp> Matcher<R> {
4949
}
5050
}
5151

52-
pub fn matches<'a>(&self, mut input: &'a str) -> Option<Vec<&'a str>> {
52+
pub fn matches<'a>(
53+
&self,
54+
mut input: &'a str,
55+
) -> Option<Vec<Option<&'a str>>> {
5356
let prefix_len = self.prefix.len();
5457
let suffix_len = self.suffix.len();
5558
let input_len = input.len();
@@ -82,7 +85,7 @@ impl<R: RegExp> Matcher<R> {
8285
return None;
8386
}
8487
}
85-
Some(vec![input])
88+
Some(vec![Some(input)])
8689
}
8790
InnerMatcher::RegExp { regexp, .. } => {
8891
regexp.as_ref().unwrap().matches(input)

src/parser.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ where
386386
if name_token.is_some() || regexp_or_wildcard_token.is_some() {
387387
let mut prefix = String::new();
388388
if let Some(char_token) = char_token {
389-
prefix = char_token.value.to_owned();
389+
char_token.value.clone_into(&mut prefix);
390390
}
391391
if !prefix.is_empty() && prefix != options.prefix_code_point {
392392
parser.pending_fixed_value.push_str(&prefix);

src/quirks.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ impl RegExp for EcmaRegexp {
176176
Ok(EcmaRegexp(pattern.to_string()))
177177
}
178178

179-
fn matches<'a>(&self, text: &'a str) -> Option<Vec<&'a str>> {
179+
fn matches<'a>(&self, text: &'a str) -> Option<Vec<Option<&'a str>>> {
180180
let regexp = regex::Regex::parse(&self.0).ok()?;
181181
regexp.matches(text)
182182
}

src/regexp.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ pub trait RegExp: Sized {
1111
/// of captures. The matches are returned in the order they appear in the
1212
/// regular expression. It is **not** prefixed with the full match. For groups
1313
/// that occur in the regular expression, but did not match, the corresponding
14-
/// capture should be the empty string ("").
14+
/// capture should be `None`.
1515
///
1616
/// Returns `None` if the text does not match the regular expression.
17-
fn matches<'a>(&self, text: &'a str) -> Option<Vec<&'a str>>;
17+
fn matches<'a>(&self, text: &'a str) -> Option<Vec<Option<&'a str>>>;
1818
}
1919

2020
impl RegExp for regex::Regex {
@@ -26,13 +26,13 @@ impl RegExp for regex::Regex {
2626
regex::Regex::new(pattern).map_err(|_| ())
2727
}
2828

29-
fn matches<'a>(&self, text: &'a str) -> Option<Vec<&'a str>> {
29+
fn matches<'a>(&self, text: &'a str) -> Option<Vec<Option<&'a str>>> {
3030
let captures = self.captures(text)?;
3131

3232
let captures = captures
3333
.iter()
3434
.skip(1)
35-
.map(|c| c.map(|m| m.as_str()).unwrap_or(""))
35+
.map(|c| c.map(|m| m.as_str()))
3636
.collect();
3737

3838
Some(captures)

src/testdata/urlpatterntestdata.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2417,7 +2417,6 @@
24172417
"expected_obj": "error"
24182418
},
24192419
{
2420-
"skip": "bug in rust-url: https://github.com/servo/rust-url/pull/718",
24212420
"pattern": [{ "hostname": "bad|hostname" }],
24222421
"expected_obj": "error"
24232422
},
@@ -2619,6 +2618,7 @@
26192618
}
26202619
},
26212620
{
2621+
"skip": "only works in ecmascript variety of regex",
26222622
"pattern": [{ "pathname": "*{}**?" }],
26232623
"inputs": [{ "pathname": "foobar" }],
26242624
"expected_obj": {

src/tokenizer.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
22

3-
use derive_more::Display;
4-
53
use crate::error::TokenizerError;
64
use crate::Error;
75

86
// Ref: https://wicg.github.io/urlpattern/#tokens
97
// Ref: https://wicg.github.io/urlpattern/#tokenizing
108

119
// Ref: https://wicg.github.io/urlpattern/#token-type
12-
#[derive(Debug, Display, Clone, Eq, PartialEq)]
10+
#[derive(Debug, Clone, Eq, PartialEq)]
1311
pub enum TokenType {
1412
Open,
1513
Close,

0 commit comments

Comments
 (0)