Skip to content

Commit 5d855c0

Browse files
committed
Turbopack: chore: Avoid string clones in Glob::parse by using RcStr
1 parent 9d38be6 commit 5d855c0

File tree

1 file changed

+19
-23
lines changed
  • turbopack/crates/turbo-tasks-fs/src

1 file changed

+19
-23
lines changed

turbopack/crates/turbo-tasks-fs/src/glob.rs

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,21 @@ use crate::globset::parse;
2424
#[derive(Debug, Clone)]
2525
#[serde(into = "GlobForm", try_from = "GlobForm")]
2626
pub struct Glob {
27-
glob: String,
27+
glob: RcStr,
2828
#[turbo_tasks(trace_ignore)]
2929
opts: GlobOptions,
3030
#[turbo_tasks(trace_ignore)]
3131
regex: Regex,
3232
#[turbo_tasks(trace_ignore)]
3333
directory_match_regex: Regex,
3434
}
35+
3536
impl PartialEq for Glob {
3637
fn eq(&self, other: &Self) -> bool {
3738
self.glob == other.glob
3839
}
3940
}
41+
4042
impl Eq for Glob {}
4143

4244
impl Display for Glob {
@@ -47,6 +49,7 @@ impl Display for Glob {
4749
#[derive(
4850
Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, Default, TaskInput, TraceRawVcs, Debug,
4951
)]
52+
5053
pub struct GlobOptions {
5154
/// Whether the glob is a partial match.
5255
/// Allows glob to match any part of the given string(s).
@@ -58,9 +61,10 @@ pub struct GlobOptions {
5861

5962
#[derive(Serialize, Deserialize)]
6063
struct GlobForm {
61-
glob: String,
64+
glob: RcStr,
6265
opts: GlobOptions,
6366
}
67+
6468
impl From<Glob> for GlobForm {
6569
fn from(value: Glob) -> Self {
6670
Self {
@@ -69,10 +73,11 @@ impl From<Glob> for GlobForm {
6973
}
7074
}
7175
}
76+
7277
impl TryFrom<GlobForm> for Glob {
7378
type Error = anyhow::Error;
7479
fn try_from(value: GlobForm) -> Result<Self, Self::Error> {
75-
Glob::parse(&value.glob, value.opts)
80+
Glob::parse(value.glob, value.opts)
7681
}
7782
}
7883

@@ -92,33 +97,25 @@ impl Glob {
9297
self.directory_match_regex.is_match(path.as_bytes())
9398
}
9499

95-
pub fn parse(input: &str, opts: GlobOptions) -> Result<Glob> {
96-
let (glob_re, directory_match_re) = parse(input, opts)?;
100+
pub fn parse(input: RcStr, opts: GlobOptions) -> Result<Glob> {
101+
let (glob_re, directory_match_re) = parse(&input, opts)?;
97102
let regex = new_regex(glob_re.as_str());
98103
let directory_match_regex = new_regex(directory_match_re.as_str());
99104

100105
Ok(Glob {
101-
glob: input.to_string(),
106+
glob: input,
102107
opts,
103108
regex,
104109
directory_match_regex,
105110
})
106111
}
107112
}
108113

109-
impl TryFrom<&str> for Glob {
110-
type Error = anyhow::Error;
111-
112-
fn try_from(value: &str) -> Result<Self, Self::Error> {
113-
Glob::parse(value, GlobOptions::default())
114-
}
115-
}
116-
117114
#[turbo_tasks::value_impl]
118115
impl Glob {
119116
#[turbo_tasks::function]
120117
pub fn new(glob: RcStr, opts: GlobOptions) -> Result<Vc<Self>> {
121-
Ok(Self::cell(Glob::parse(glob.as_str(), opts)?))
118+
Ok(Self::cell(Glob::parse(glob, opts)?))
122119
}
123120

124121
#[turbo_tasks::function]
@@ -166,8 +163,7 @@ fn new_regex(pattern: &str) -> Regex {
166163
mod tests {
167164
use rstest::*;
168165

169-
use super::Glob;
170-
use crate::glob::GlobOptions;
166+
use super::*;
171167

172168
#[rstest]
173169
#[case::file("file.js", "file.js")]
@@ -238,7 +234,7 @@ mod tests {
238234
#[case::alternatives_empty2("react{,-dom}", "react-dom")]
239235
#[case::alternatives_chars("[abc]", "b")]
240236
fn glob_match(#[case] glob: &str, #[case] path: &str) {
241-
let glob = Glob::parse(glob, GlobOptions::default()).unwrap();
237+
let glob = Glob::parse(RcStr::from(glob), GlobOptions::default()).unwrap();
242238

243239
println!("{glob:?} {path}");
244240

@@ -253,7 +249,7 @@ mod tests {
253249
)]
254250
#[case::star("*", "/foo")]
255251
fn glob_not_matching(#[case] glob: &str, #[case] path: &str) {
256-
let glob = Glob::parse(glob, GlobOptions::default()).unwrap();
252+
let glob = Glob::parse(RcStr::from(glob), GlobOptions::default()).unwrap();
257253

258254
println!("{glob:?} {path}");
259255

@@ -272,7 +268,7 @@ mod tests {
272268
#[case::globstar_in_dir_partial("dir/**/sub/file.js", "dir/a/b/sub")]
273269
#[case::globstar_in_dir_partial("dir/**/sub/file.js", "dir/a/b/sub/file.js")]
274270
fn glob_can_match_directory(#[case] glob: &str, #[case] path: &str) {
275-
let glob = Glob::parse(glob, GlobOptions::default()).unwrap();
271+
let glob = Glob::parse(RcStr::from(glob), GlobOptions::default()).unwrap();
276272

277273
println!("{glob:?} {path}");
278274

@@ -282,7 +278,7 @@ mod tests {
282278
#[case::dir_and_file_partial("dir/file.js", "dir/file.js")] // even if there was a dir, named `file.js` we know the glob wasn't intended to match it.
283279
#[case::alternatives_chars("[abc]", "b")]
284280
fn glob_not_can_match_directory(#[case] glob: &str, #[case] path: &str) {
285-
let glob = Glob::parse(glob, GlobOptions::default()).unwrap();
281+
let glob = Glob::parse(RcStr::from(glob), GlobOptions::default()).unwrap();
286282

287283
println!("{glob:?} {path}");
288284

@@ -297,7 +293,7 @@ mod tests {
297293
// This is a possibly surprising case.
298294
#[case::dir_match("node_modules/foo", "my_node_modules/foobar")]
299295
fn partial_glob_match(#[case] glob: &str, #[case] path: &str) {
300-
let glob = Glob::parse(glob, GlobOptions { contains: true }).unwrap();
296+
let glob = Glob::parse(RcStr::from(glob), GlobOptions { contains: true }).unwrap();
301297

302298
println!("{glob:?} {path}");
303299

@@ -311,7 +307,7 @@ mod tests {
311307
// This is a possibly surprising case
312308
#[case::dir_match("/node_modules/", "node_modules/")]
313309
fn partial_glob_not_matching(#[case] glob: &str, #[case] path: &str) {
314-
let glob = Glob::parse(glob, GlobOptions { contains: true }).unwrap();
310+
let glob = Glob::parse(RcStr::from(glob), GlobOptions { contains: true }).unwrap();
315311

316312
println!("{glob:?} {path}");
317313

0 commit comments

Comments
 (0)