Skip to content
Open
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
2 changes: 1 addition & 1 deletion benches/parse_patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ fn bench_parse_shipping_groups_summary(c: &mut Criterion) {
b.iter(|| {
let input = quirks::process_construct_pattern_input(
black_box(quirks::StringOrInit::String(
"component-ShippingGroupsSummary.*.js".to_owned()
"component-ShippingGroupsSummary.*.js".into()
)),
black_box(Some("https://example.test/web/")),
);
Expand Down
44 changes: 24 additions & 20 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -659,10 +659,11 @@ mod tests {

#[derive(Debug, Deserialize)]
#[serde(untagged)]
#[serde(bound(deserialize = "'de: 'a"))]
#[allow(clippy::large_enum_variant)]
enum ExpectedMatch {
enum ExpectedMatch<'a> {
String(String),
MatchResult(MatchResult),
MatchResult(MatchResult<'a>),
}

#[derive(Debug, Deserialize)]
Expand All @@ -674,28 +675,30 @@ mod tests {
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum StringOrInitOrOptions {
pub enum StringOrInitOrOptions<'a> {
Options(UrlPatternOptions),
StringOrInit(quirks::StringOrInit),
StringOrInit(quirks::StringOrInit<'a>),
}

#[derive(Debug, Deserialize)]
struct TestCase {
#[serde(bound(deserialize = "'de: 'a"))]
struct TestCase<'a> {
skip: Option<String>,
pattern: Vec<StringOrInitOrOptions>,
pattern: Vec<StringOrInitOrOptions<'a>>,
#[serde(default)]
inputs: Vec<quirks::StringOrInit>,
expected_obj: Option<quirks::StringOrInit>,
expected_match: Option<ExpectedMatch>,
inputs: Vec<quirks::StringOrInit<'a>>,
expected_obj: Option<quirks::StringOrInit<'a>>,
expected_match: Option<ExpectedMatch<'a>>,
#[serde(default)]
exactly_empty_components: Vec<String>,
}

#[derive(Debug, Deserialize)]
struct MatchResult {
#[serde(bound(deserialize = "'de: 'a"))]
struct MatchResult<'a> {
#[serde(deserialize_with = "deserialize_match_result_inputs")]
#[serde(default)]
inputs: Option<(quirks::StringOrInit, Option<String>)>,
inputs: Option<(quirks::StringOrInit<'a>, Option<String>)>,

protocol: Option<ComponentResult>,
username: Option<ComponentResult>,
Expand All @@ -707,17 +710,17 @@ mod tests {
hash: Option<ComponentResult>,
}

fn deserialize_match_result_inputs<'de, D>(
fn deserialize_match_result_inputs<'a, D>(
deserializer: D,
) -> Result<Option<(quirks::StringOrInit, Option<String>)>, D::Error>
) -> Result<Option<(quirks::StringOrInit<'a>, Option<String>)>, D::Error>
where
D: serde::Deserializer<'de>,
D: serde::Deserializer<'a>,
{
#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum MatchResultInputs {
OneArgument((quirks::StringOrInit,)),
TwoArguments(quirks::StringOrInit, String),
enum MatchResultInputs<'a> {
OneArgument((quirks::StringOrInit<'a>,)),
TwoArguments(quirks::StringOrInit<'a>, String),
}

let res = Option::<MatchResultInputs>::deserialize(deserializer)?;
Expand Down Expand Up @@ -811,7 +814,7 @@ mod tests {
..
}) = &input
{
base_url = Some(url.clone())
base_url = Some(url.clone().into())
}

macro_rules! assert_field {
Expand Down Expand Up @@ -921,7 +924,8 @@ mod tests {

let input = input.unwrap_or_else(|| StringOrInit::Init(Default::default()));

let expected_input = (input.clone(), base_url.clone());
let expected_input =
(input.clone(), base_url.clone().map(|s| s.to_string()));

let match_input = quirks::process_match_input(input, base_url.as_deref());

Expand Down Expand Up @@ -1058,7 +1062,7 @@ mod tests {
#[test]
fn issue46() {
quirks::process_construct_pattern_input(
quirks::StringOrInit::String(":café://:foo".to_owned()),
quirks::StringOrInit::String(":café://:foo".to_owned().into()),
None,
)
.unwrap();
Expand Down
23 changes: 13 additions & 10 deletions src/quirks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use serde::Deserialize;
use serde::Serialize;
use std::borrow::Cow;
use url::Url;

pub use crate::Error;
Expand Down Expand Up @@ -36,8 +37,8 @@ pub struct UrlPatternInit {
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum StringOrInit {
String(String),
pub enum StringOrInit<'a> {
String(Cow<'a, str>),
Init(UrlPatternInit),
}

Expand Down Expand Up @@ -106,7 +107,7 @@ impl<R: RegExp> From<Component<R>> for UrlPatternComponent {
fn from(component: Component<R>) -> Self {
let regexp_string = component
.regexp
.map(|r| r.pattern_string())
.map(|r| r.pattern_string().to_owned())
.unwrap_or_default();
Self {
pattern_string: component.pattern_string,
Expand Down Expand Up @@ -166,7 +167,9 @@ impl<R: RegExp> From<crate::matcher::InnerMatcher<R>> for InnerMatcher {
allow_empty,
},
crate::matcher::InnerMatcher::RegExp { regexp } => Self::RegExp {
regexp: regexp.map(|r| r.pattern_string()).unwrap_or_default(),
regexp: regexp
.map(|r| r.pattern_string().to_owned())
.unwrap_or_default(),
},
}
}
Expand Down Expand Up @@ -196,8 +199,8 @@ impl RegExp for EcmaRegexp {
regexp.matches(text)
}

fn pattern_string(&self) -> String {
self.0.clone()
fn pattern_string(&self) -> &str {
self.0.as_ref()
}
}

Expand Down Expand Up @@ -230,12 +233,12 @@ pub fn parse_pattern_as_lib<R: RegExp>(
Ok(pattern)
}

pub type Inputs = (StringOrInit, Option<String>);
pub type Inputs<'a> = (StringOrInit<'a>, Option<String>);

pub fn process_match_input(
input: StringOrInit,
pub fn process_match_input<'a>(
input: StringOrInit<'a>,
base_url_str: Option<&str>,
) -> Result<Option<(crate::UrlPatternMatchInput, Inputs)>, Error> {
) -> Result<Option<(crate::UrlPatternMatchInput, Inputs<'a>)>, Error> {
let mut inputs = (input.clone(), None);
let init = match input {
StringOrInit::String(url) => {
Expand Down
6 changes: 3 additions & 3 deletions src/regexp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub trait RegExp: Sized {
/// Returns `None` if the text does not match the regular expression.
fn matches<'a>(&self, text: &'a str) -> Option<Vec<Option<&'a str>>>;

fn pattern_string(&self) -> String;
fn pattern_string(&self) -> &str;
}

impl RegExp for regex::Regex {
Expand All @@ -41,7 +41,7 @@ impl RegExp for regex::Regex {
Some(captures)
}

fn pattern_string(&self) -> String {
self.as_str().to_string()
fn pattern_string(&self) -> &str {
self.as_str()
}
}