From 05be16ba4547eb39368b875b3ee0cc1277f0118b Mon Sep 17 00:00:00 2001 From: hardfist Date: Sun, 17 May 2026 12:44:45 +0800 Subject: [PATCH 1/5] perf: avoid utf8 conversion when appending extensions --- src/lib.rs | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 707a1f27..5479e96b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,6 +62,8 @@ mod tsconfig; #[cfg(test)] mod tests; +#[cfg(unix)] +use std::os::unix::ffi::OsStrExt; use std::{ borrow::Cow, cmp::Ordering, @@ -692,20 +694,44 @@ impl ResolverGeneric { return Ok(None); } let path = path.path().as_os_str(); - // 8 is wild guess for max extension length - let mut path_with_extension_buffer = String::with_capacity(path.len() + 8); - path_with_extension_buffer.push_str(&path.to_string_lossy()); - let base_len = path_with_extension_buffer.len(); - for extension in extensions { - path_with_extension_buffer.truncate(base_len); - path_with_extension_buffer.push_str(extension); - let cached_path = self.cache.value(Path::new(&path_with_extension_buffer)); - if let Some(path) = self.load_alias_or_file(&cached_path, ctx).await? { - return Ok(Some(path)); + #[cfg(unix)] + { + let path = path.as_bytes(); + let mut path_with_extension_buffer = Vec::with_capacity(path.len() + 8); + path_with_extension_buffer.extend_from_slice(path); + let base_len = path_with_extension_buffer.len(); + + for extension in extensions { + path_with_extension_buffer.truncate(base_len); + path_with_extension_buffer.extend_from_slice(extension.as_bytes()); + let cached_path = self + .cache + .value(Path::new(OsStr::from_bytes(&path_with_extension_buffer))); + if let Some(path) = self.load_alias_or_file(&cached_path, ctx).await? { + return Ok(Some(path)); + } } + return Ok(None); + } + + #[cfg(not(unix))] + { + // 8 is wild guess for max extension length + let mut path_with_extension_buffer = String::with_capacity(path.len() + 8); + path_with_extension_buffer.push_str(&path.to_string_lossy()); + let base_len = path_with_extension_buffer.len(); + + for extension in extensions { + path_with_extension_buffer.truncate(base_len); + path_with_extension_buffer.push_str(extension); + let cached_path = self.cache.value(Path::new(&path_with_extension_buffer)); + if let Some(path) = self.load_alias_or_file(&cached_path, ctx).await? { + return Ok(Some(path)); + } + } + Ok(None) } - Ok(None) } #[cfg_attr(feature="enable_instrument", tracing::instrument(level=tracing::Level::DEBUG, skip_all, fields(path = %cached_path.path().to_string_lossy())))] From 16c17954e885f889b017d8aaa0d74792032cd837 Mon Sep 17 00:00:00 2001 From: hardfist Date: Sun, 17 May 2026 12:48:18 +0800 Subject: [PATCH 2/5] perf: skip impossible bare alias checks for absolute paths --- src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 5479e96b..a9bef15a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1276,7 +1276,12 @@ impl ResolverGeneric { aliases: &Alias, ctx: &mut Ctx, ) -> ResolveResult { + let specifier_is_absolute = Path::new(specifier).is_absolute(); for (alias_key_raw, specifiers) in aliases { + let alias_key_without_exact = alias_key_raw.strip_suffix('$').unwrap_or(alias_key_raw); + if specifier_is_absolute && !Path::new(alias_key_without_exact).is_absolute() { + continue; + } let alias_key = if let Some(alias_key) = alias_key_raw.strip_suffix('$') { if alias_key != specifier { continue; From 278d640728b9452d595d617e4978560b9432b71b Mon Sep 17 00:00:00 2001 From: hardfist Date: Sun, 17 May 2026 12:53:36 +0800 Subject: [PATCH 3/5] perf: partition aliases by request path kind --- src/lib.rs | 83 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a9bef15a..49ae671c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -115,6 +115,10 @@ pub type Resolver = ResolverGeneric; /// Generic implementation of the resolver, can be configured by the [FileSystem] trait pub struct ResolverGeneric { options: ResolveOptions, + absolute_alias: Alias, + relative_alias: Alias, + absolute_fallback: Alias, + relative_fallback: Alias, cache: Arc>, #[cfg(feature = "yarn_pnp")] pnp_manifest: Arc>, @@ -139,8 +143,15 @@ impl Default for ResolverGeneric { impl ResolverGeneric { pub fn new(options: ResolveOptions) -> Self { + let options = options.sanitize(); + let (absolute_alias, relative_alias) = Self::partition_alias(&options.alias); + let (absolute_fallback, relative_fallback) = Self::partition_alias(&options.fallback); Self { - options: options.sanitize(), + options, + absolute_alias, + relative_alias, + absolute_fallback, + relative_fallback, cache: Arc::new(Cache::new(Fs::default())), #[cfg(feature = "yarn_pnp")] pnp_manifest: Arc::new(arc_swap::ArcSwapOption::empty()), @@ -152,9 +163,42 @@ impl ResolverGeneric { } impl ResolverGeneric { + fn partition_alias(aliases: &Alias) -> (Alias, Alias) { + let mut absolute_alias = Vec::new(); + let mut relative_alias = Vec::new(); + for (key, values) in aliases { + let key_without_exact = key.strip_suffix('$').unwrap_or(key); + if Path::new(key_without_exact).is_absolute() { + absolute_alias.push((key.clone(), values.clone())); + } else { + relative_alias.push((key.clone(), values.clone())); + } + } + (absolute_alias, relative_alias) + } + + fn aliases_for<'a>( + specifier: &str, + absolute_aliases: &'a Alias, + relative_aliases: &'a Alias, + ) -> &'a Alias { + if Path::new(specifier).is_absolute() { + absolute_aliases + } else { + relative_aliases + } + } + pub fn new_with_file_system(file_system: Fs, options: ResolveOptions) -> Self { + let options = options.sanitize(); + let (absolute_alias, relative_alias) = Self::partition_alias(&options.alias); + let (absolute_fallback, relative_fallback) = Self::partition_alias(&options.fallback); Self { - options: options.sanitize(), + options, + absolute_alias, + relative_alias, + absolute_fallback, + relative_fallback, cache: Arc::new(Cache::new(file_system)), #[cfg(feature = "yarn_pnp")] pnp_manifest: Arc::new(arc_swap::ArcSwapOption::empty()), @@ -167,8 +211,15 @@ impl ResolverGeneric { /// Clone the resolver using the same underlying cache. #[must_use] pub fn clone_with_options(&self, options: ResolveOptions) -> Self { + let options = options.sanitize(); + let (absolute_alias, relative_alias) = Self::partition_alias(&options.alias); + let (absolute_fallback, relative_fallback) = Self::partition_alias(&options.fallback); Self { - options: options.sanitize(), + options, + absolute_alias, + relative_alias, + absolute_fallback, + relative_fallback, cache: Arc::clone(&self.cache), #[cfg(feature = "yarn_pnp")] pnp_manifest: Arc::clone(&self.pnp_manifest), @@ -332,7 +383,12 @@ impl ResolverGeneric { // enhanced-resolve: try alias if let Some(path) = self - .load_alias(cached_path, specifier, &self.options.alias, ctx) + .load_alias( + cached_path, + specifier, + Self::aliases_for(specifier, &self.absolute_alias, &self.relative_alias), + ctx, + ) .await? { return Ok(path); @@ -372,7 +428,12 @@ impl ResolverGeneric { } // enhanced-resolve: try fallback self - .load_alias(cached_path, specifier, &self.options.fallback, ctx) + .load_alias( + cached_path, + specifier, + Self::aliases_for(specifier, &self.absolute_fallback, &self.relative_fallback), + ctx, + ) .await .and_then(|value| value.ok_or(err)) } @@ -826,7 +887,12 @@ impl ResolverGeneric { // enhanced-resolve: try file as alias let alias_specifier = cached_path.path().to_string_lossy(); if let Some(path) = self - .load_alias(cached_path, &alias_specifier, &self.options.alias, ctx) + .load_alias( + cached_path, + &alias_specifier, + Self::aliases_for(&alias_specifier, &self.absolute_alias, &self.relative_alias), + ctx, + ) .await? { return Ok(Some(path)); @@ -1276,12 +1342,7 @@ impl ResolverGeneric { aliases: &Alias, ctx: &mut Ctx, ) -> ResolveResult { - let specifier_is_absolute = Path::new(specifier).is_absolute(); for (alias_key_raw, specifiers) in aliases { - let alias_key_without_exact = alias_key_raw.strip_suffix('$').unwrap_or(alias_key_raw); - if specifier_is_absolute && !Path::new(alias_key_without_exact).is_absolute() { - continue; - } let alias_key = if let Some(alias_key) = alias_key_raw.strip_suffix('$') { if alias_key != specifier { continue; From e6517c6885528a38a999e951ac288f13bf8f596e Mon Sep 17 00:00:00 2001 From: hardfist Date: Sun, 17 May 2026 12:58:00 +0800 Subject: [PATCH 4/5] perf: precheck path aliases before string conversion --- src/lib.rs | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 49ae671c..904a6e1d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -189,6 +189,22 @@ impl ResolverGeneric { } } + fn path_alias_may_match(path: &Path, aliases: &Alias) -> bool { + if aliases.is_empty() { + return false; + } + let Some(path) = path.to_str() else { + return true; + }; + aliases.iter().any(|(alias_key_raw, _)| { + if let Some(alias_key) = alias_key_raw.strip_suffix('$') { + alias_key == path + } else { + Self::strip_package_name(path, alias_key_raw).is_some() + } + }) + } + pub fn new_with_file_system(file_system: Fs, options: ResolveOptions) -> Self { let options = options.sanitize(); let (absolute_alias, relative_alias) = Self::partition_alias(&options.alias); @@ -885,17 +901,20 @@ impl ResolverGeneric { } } // enhanced-resolve: try file as alias - let alias_specifier = cached_path.path().to_string_lossy(); - if let Some(path) = self - .load_alias( - cached_path, - &alias_specifier, - Self::aliases_for(&alias_specifier, &self.absolute_alias, &self.relative_alias), - ctx, - ) - .await? - { - return Ok(Some(path)); + let path = cached_path.path(); + let aliases = if path.is_absolute() { + &self.absolute_alias + } else { + &self.relative_alias + }; + if Self::path_alias_may_match(path, aliases) { + let alias_specifier = path.to_string_lossy(); + if let Some(path) = self + .load_alias(cached_path, &alias_specifier, aliases, ctx) + .await? + { + return Ok(Some(path)); + } } if cached_path.is_file(&self.cache.fs, ctx).await && self.check_restrictions(cached_path.path()) { From 91e539f606599e4e63335e2bb9716d4a4e5f8ef4 Mon Sep 17 00:00:00 2001 From: hardfist Date: Mon, 18 May 2026 10:40:53 +0800 Subject: [PATCH 5/5] chore: fix clippy warnings --- benches/resolver.rs | 47 +++++++++++++------------ examples/resolver.rs | 25 +++++++------ src/lib.rs | 9 +++-- src/tests/dependencies.rs | 15 +++++--- src/tests/exports_field.rs | 2 +- src/tests/incorrect_description_file.rs | 2 +- src/tests/missing.rs | 4 +-- src/tests/package_json.rs | 14 ++++---- src/tests/pnp.rs | 9 +++-- src/tests/restrictions.rs | 10 +++--- src/tests/symlink.rs | 4 +-- src/tests/tsconfig_paths.rs | 2 +- tests/integration_test.rs | 2 +- 13 files changed, 77 insertions(+), 68 deletions(-) diff --git a/benches/resolver.rs b/benches/resolver.rs index 0af1fe83..deb6ef7d 100644 --- a/benches/resolver.rs +++ b/benches/resolver.rs @@ -1,10 +1,11 @@ +#![allow(clippy::significant_drop_tightening)] + #[cfg(target_family = "wasm")] use std::alloc::System; use std::{ alloc::{GlobalAlloc, Layout}, env, fs, fs::read_to_string, - future::Future, io::{self, Write}, path::{Path, PathBuf}, sync::Arc, @@ -42,7 +43,7 @@ unsafe impl GlobalAlloc for NeverGrowInPlaceAllocator { } unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - self.allocator.dealloc(ptr, layout) + self.allocator.dealloc(ptr, layout); } } @@ -170,14 +171,12 @@ fn resolver_with_many_extensions() -> rspack_resolver::Resolver { }) } -fn create_async_resolve_task( +async fn create_async_resolve_task( rspack_resolver: Arc, path: PathBuf, request: String, -) -> impl Future { - async move { - let _ = rspack_resolver.resolve(path, &request).await; - } +) { + let _ = rspack_resolver.resolve(path, &request).await; } fn bench_resolver(c: &mut Criterion) { @@ -197,9 +196,11 @@ fn bench_resolver(c: &mut Criterion) { runtime::Builder::new_current_thread().enable_all().build().unwrap().block_on(async { for (path, request) in &data { let r = rspack_resolver(false).resolve(path, request).await; - if !r.is_ok() { - panic!("resolve failed {path:?} {request},\n\nplease run `pnpm install --ignore-workspace` in `/benches` before running the benchmarks"); - } + assert!( + r.is_ok(), + "resolve failed {} {request},\n\nplease run `pnpm install --ignore-workspace` in `/benches` before running the benchmarks", + path.display(), + ); } }); @@ -255,7 +256,7 @@ fn bench_resolver(c: &mut Criterion) { || { rspack_resolver.clear_cache(); }, - |_| async { + |()| async { for (path, request) in data { _ = rspack_resolver.resolve(path, request).await; } @@ -278,10 +279,10 @@ fn bench_resolver(c: &mut Criterion) { || { rspack_resolver.clear_cache(); }, - |_| async { + |()| async { for (path, request) in data { _ = rspack_resolver - .resolve(path, &format!("{}/bad", request)) + .resolve(path, &format!("{request}/bad")) .await; } }, @@ -300,16 +301,16 @@ fn bench_resolver(c: &mut Criterion) { || { rspack_resolver.clear_cache(); }, - |_| { + |()| { runner.block_on(async { let mut join_set = JoinSet::new(); - data.iter().for_each(|(path, request)| { + for (path, request) in data { join_set.spawn(create_async_resolve_task( - rspack_resolver.clone(), - path.to_path_buf(), - request.to_string(), + Arc::clone(&rspack_resolver), + (*path).clone(), + (*request).clone(), )); - }); + } let _ = join_set.join_all().await; }); }, @@ -328,7 +329,7 @@ fn bench_resolver(c: &mut Criterion) { || { rspack_resolver.clear_cache(); }, - |_| async { + |()| async { for i in data.clone() { assert!( rspack_resolver @@ -357,9 +358,9 @@ fn bench_resolver(c: &mut Criterion) { data.clone().for_each(|i| { join_set.spawn(create_async_resolve_task( - rspack_resolver.clone(), + Arc::clone(&rspack_resolver), symlink_test_dir.clone(), - format!("./file{i}").to_string(), + format!("./file{i}"), )); }); join_set.join_all().await; @@ -381,7 +382,7 @@ fn bench_resolver(c: &mut Criterion) { || { rspack_resolver.clear_cache(); }, - |_| async { + |()| async { for i in data.clone() { let _ = rspack_resolver .resolve(pnp_workspace.join(format!("{i}")), "preact") diff --git a/examples/resolver.rs b/examples/resolver.rs index 4616a6a1..905b7e5d 100644 --- a/examples/resolver.rs +++ b/examples/resolver.rs @@ -1,7 +1,7 @@ -///! See documentation at +//! See documentation at use std::{env, path::PathBuf}; -use rspack_resolver::{AliasValue, ResolveOptions, Resolver}; +use rspack_resolver::{AliasValue, ResolveContext, ResolveOptions, Resolver}; #[tokio::main] async fn main() { @@ -9,13 +9,18 @@ async fn main() { assert!( path.is_dir(), - "{path:?} must be a directory that will be resolved against." + "{} must be a directory that will be resolved against.", + path.display() + ); + assert!( + path.is_absolute(), + "{} must be an absolute path.", + path.display() ); - assert!(path.is_absolute(), "{path:?} must be an absolute path.",); let specifier = env::args().nth(2).expect("specifier"); - println!("path: {path:?}"); + println!("path: {}", path.display()); println!("specifier: {specifier}"); let options = ResolveOptions { @@ -29,21 +34,21 @@ async fn main() { // condition_names: vec!["node".into(), "require".into()], ..ResolveOptions::default() }; - let mut ctx = Default::default(); + let mut ctx = ResolveContext::default(); match Resolver::new(options) .resolve_with_context(path, &specifier, &mut ctx) .await { Err(error) => println!("Error: {error}"), - Ok(resolution) => println!("Resolved: {:?}", resolution.full_path()), - }; + Ok(resolution) => println!("Resolved: {}", resolution.full_path().display()), + } let mut sorted_file_deps = ctx.file_dependencies.iter().collect::>(); sorted_file_deps.sort(); - println!("file_deps: {:#?}", sorted_file_deps); + println!("file_deps: {sorted_file_deps:#?}"); let mut sorted_missing = ctx.missing_dependencies.iter().collect::>(); sorted_missing.sort(); - println!("missing_deps: {:#?}", sorted_missing); + println!("missing_deps: {sorted_missing:#?}"); } diff --git a/src/lib.rs b/src/lib.rs index 904a6e1d..74da0781 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -197,11 +197,10 @@ impl ResolverGeneric { return true; }; aliases.iter().any(|(alias_key_raw, _)| { - if let Some(alias_key) = alias_key_raw.strip_suffix('$') { - alias_key == path - } else { - Self::strip_package_name(path, alias_key_raw).is_some() - } + alias_key_raw.strip_suffix('$').map_or_else( + || Self::strip_package_name(path, alias_key_raw).is_some(), + |alias_key| alias_key == path, + ) }) } diff --git a/src/tests/dependencies.rs b/src/tests/dependencies.rs index cf0e3657..49c933fc 100644 --- a/src/tests/dependencies.rs +++ b/src/tests/dependencies.rs @@ -99,14 +99,19 @@ mod windows { for (name, context, request, result, file_dependencies, missing_dependencies) in data { let mut ctx = ResolveContext::default(); let path = PathBuf::from(context); - let resolved = resolver + let resolution = resolver .resolve_with_context(path, request, &mut ctx) .await .map(|r| r.full_path()); - assert_eq!(resolved, Ok(PathBuf::from(result))); - let file_dependencies = FxHashSet::from_iter(file_dependencies.iter().map(PathBuf::from)); - let missing_dependencies = - FxHashSet::from_iter(missing_dependencies.iter().map(PathBuf::from)); + assert_eq!(resolution, Ok(PathBuf::from(result))); + let file_dependencies = file_dependencies + .iter() + .map(PathBuf::from) + .collect::>(); + let missing_dependencies = missing_dependencies + .iter() + .map(PathBuf::from) + .collect::>(); assert_eq!(ctx.file_dependencies, file_dependencies, "{name}"); assert_eq!(ctx.missing_dependencies, missing_dependencies, "{name}"); } diff --git a/src/tests/exports_field.rs b/src/tests/exports_field.rs index cfbbc8b1..61f8d0f5 100644 --- a/src/tests/exports_field.rs +++ b/src/tests/exports_field.rs @@ -393,7 +393,7 @@ fn exports_field(value: simd_json::value::OwnedValue) -> package_json::JSONValue #[tokio::test] async fn test_cases() { - let test_cases = [ + let test_cases = vec![ TestCase { name: "sample #1", expect: Some(vec!["./dist/test/file.js"]), diff --git a/src/tests/incorrect_description_file.rs b/src/tests/incorrect_description_file.rs index 42b82023..5b327589 100644 --- a/src/tests/incorrect_description_file.rs +++ b/src/tests/incorrect_description_file.rs @@ -38,7 +38,7 @@ async fn incorrect_description_file_2() { message: String::from("EOF while parsing a value at line 1 column 0"), line: 1, column: 0, - content: Some("".to_string()), + content: Some(String::new()), }); assert!(matches!(resolution, Err(ResolveError::JSON(_)))); } diff --git a/src/tests/missing.rs b/src/tests/missing.rs index eb82a101..593415e0 100644 --- a/src/tests/missing.rs +++ b/src/tests/missing.rs @@ -98,8 +98,8 @@ async fn alias_and_extensions() { }); let mut ctx = ResolveContext::default(); - let _ = resolver.resolve_with_context(&f, "@scope-js/package-name/dir/router", &mut ctx); - let _ = resolver.resolve_with_context(&f, "react-dom/client", &mut ctx); + std::mem::drop(resolver.resolve_with_context(&f, "@scope-js/package-name/dir/router", &mut ctx)); + std::mem::drop(resolver.resolve_with_context(&f, "react-dom/client", &mut ctx)); for path in ctx.file_dependencies { assert_eq!(path, path.normalize(), "{path:?}"); diff --git a/src/tests/package_json.rs b/src/tests/package_json.rs index 59f83b5e..2d6c3c7f 100644 --- a/src/tests/package_json.rs +++ b/src/tests/package_json.rs @@ -9,7 +9,7 @@ mod tests { let mock_path = PathBuf::from("package.json"); let json_with_bom = b"\xEF\xBB\xBF{\"name\": \"example-package\"}".to_vec(); - let result = PackageJson::parse(mock_path.clone(), mock_path.clone(), json_with_bom).err(); + let result = PackageJson::parse(mock_path.clone(), mock_path, json_with_bom).err(); assert_eq!( result, @@ -23,9 +23,9 @@ mod tests { #[tokio::test] async fn test_normal_json() { let mock_path = PathBuf::from("package.json"); - let json_with_bom = r##"{"name": "example-package"}"##.as_bytes().to_vec(); + let json_with_bom = br#"{"name": "example-package"}"#.to_vec(); - let parsed = PackageJson::parse(mock_path.clone(), mock_path.clone(), json_with_bom).unwrap(); + let parsed = PackageJson::parse(mock_path.clone(), mock_path, json_with_bom).unwrap(); assert_eq!(parsed.name.unwrap(), "example-package"); } @@ -33,9 +33,9 @@ mod tests { #[tokio::test] async fn test_broken_json() { let mock_path = PathBuf::from("package.json"); - let json_with_bom = r##"{"broken":"string"##.as_bytes().to_vec(); + let json_with_bom = br#"{"broken":"string"#.to_vec(); - let parsed_err = PackageJson::parse(mock_path.clone(), mock_path.clone(), json_with_bom).err(); + let parsed_err = PackageJson::parse(mock_path.clone(), mock_path, json_with_bom).err(); assert_eq!( parsed_err, @@ -50,9 +50,9 @@ mod tests { #[tokio::test] async fn test_empty_string() { let mock_path = PathBuf::from("package.json"); - let json_with_bom = " ".as_bytes().to_vec(); + let json_with_bom = b" ".to_vec(); - let parse_error = PackageJson::parse(mock_path.clone(), mock_path.clone(), json_with_bom) + let parse_error = PackageJson::parse(mock_path.clone(), mock_path, json_with_bom) .err() .unwrap(); diff --git a/src/tests/pnp.rs b/src/tests/pnp.rs index cdcd548c..2c28e0ed 100644 --- a/src/tests/pnp.rs +++ b/src/tests/pnp.rs @@ -201,13 +201,13 @@ async fn resolve_pnp_with_global_cache_enabled_windows() { ..ResolveOptions::default() }); - let resolved = resolver + let resolution = resolver .resolve(&fixture, "path-to-regexp") .await .map(|r| r.full_path()) .unwrap(); - let module_root = resolved.parent().unwrap(); + let module_root = resolution.parent().unwrap(); let module_root_str = module_root.to_string_lossy().replace('\\', "/"); assert!( module_root_str.contains("/Yarn/Berry/cache/path-to-regexp"), @@ -241,13 +241,13 @@ async fn resolve_pnp_with_global_cache_enabled_unix() { ..ResolveOptions::default() }); - let resolved = resolver + let resolution = resolver .resolve(&fixture, "path-to-regexp") .await .map(|r| r.full_path()) .unwrap(); - let module_root = resolved.parent().unwrap(); + let module_root = resolution.parent().unwrap(); let module_root_str = module_root.to_string_lossy(); assert!( module_root_str.contains("/.yarn/berry/cache/path-to-regexp"), @@ -292,7 +292,6 @@ async fn resolve_pnp_transitive_dep_from_global_cache() { .to_string_lossy() .replace('\\', "/") .to_lowercase() - .to_string() }) .unwrap(); diff --git a/src/tests/restrictions.rs b/src/tests/restrictions.rs index e98e8017..1ca01a80 100644 --- a/src/tests/restrictions.rs +++ b/src/tests/restrictions.rs @@ -14,7 +14,7 @@ async fn should_respect_regexp_restriction() { let resolver1 = Resolver::new(ResolveOptions { extensions: vec![".js".into()], restrictions: vec![Restriction::Fn(Arc::new(move |path| { - path.as_os_str().to_str().map_or(false, |s| re.is_match(s)) + path.as_os_str().to_str().is_some_and(|s| re.is_match(s)) }))], ..ResolveOptions::default() }); @@ -32,7 +32,7 @@ async fn should_try_to_find_alternative_1() { extensions: vec![".js".into(), ".css".into()], main_files: vec!["index".into()], restrictions: vec![Restriction::Fn(Arc::new(move |path| { - path.as_os_str().to_str().map_or(false, |s| re.is_match(s)) + path.as_os_str().to_str().is_some_and(|s| re.is_match(s)) }))], ..ResolveOptions::default() }); @@ -65,7 +65,7 @@ async fn should_try_to_find_alternative_2() { extensions: vec![".js".into(), ".css".into()], main_fields: vec!["main".into(), "style".into()], restrictions: vec![Restriction::Fn(Arc::new(move |path| { - path.as_os_str().to_str().map_or(false, |s| re.is_match(s)) + path.as_os_str().to_str().is_some_and(|s| re.is_match(s)) }))], ..ResolveOptions::default() }); @@ -83,7 +83,7 @@ async fn should_try_to_find_alternative_3() { extensions: vec![".js".into()], main_fields: vec!["main".into(), "module".into(), "style".into()], restrictions: vec![Restriction::Fn(Arc::new(move |path| { - path.as_os_str().to_str().map_or(false, |s| re.is_match(s)) + path.as_os_str().to_str().is_some_and(|s| re.is_match(s)) }))], ..ResolveOptions::default() }); @@ -102,7 +102,7 @@ async fn should_try_to_find_alternative_4() { main_fields: vec!["main".into()], extension_alias: vec![(".js".into(), vec![".js".into(), ".jsx".into()])], restrictions: vec![Restriction::Fn(Arc::new(move |path| { - path.as_os_str().to_str().map_or(false, |s| re.is_match(s)) + path.as_os_str().to_str().is_some_and(|s| re.is_match(s)) }))], ..ResolveOptions::default() }); diff --git a/src/tests/symlink.rs b/src/tests/symlink.rs index e5c0b964..fdb3bae1 100644 --- a/src/tests/symlink.rs +++ b/src/tests/symlink.rs @@ -1,6 +1,6 @@ use std::{fs, io, path::Path}; -use crate::{ResolveOptions, Resolver}; +use crate::{ResolveContext, ResolveOptions, Resolver}; #[derive(Debug, Clone, Copy)] enum FileType { @@ -141,7 +141,7 @@ async fn test() -> io::Result<()> { .map(|r| r.full_path()); assert_eq!(filename, Ok(root.join("lib/index.js")), "{comment:?}"); - let mut ctx = &mut Default::default(); + let mut ctx = ResolveContext::default(); let resolved_path = resolver_without_symlinks .resolve_with_context(&path, request, &mut ctx) .await diff --git a/src/tests/tsconfig_paths.rs b/src/tests/tsconfig_paths.rs index 10d51fe4..599ee9d9 100644 --- a/src/tests/tsconfig_paths.rs +++ b/src/tests/tsconfig_paths.rs @@ -35,7 +35,7 @@ async fn tsconfig() { }), ..ResolveOptions::default() }); - let path = subdir.map_or(dir.clone(), |subdir| dir.join(subdir)); + let path = subdir.map_or_else(|| dir.clone(), |subdir| dir.join(subdir)); let resolved_path = resolver .resolve(&path, request) .await diff --git a/tests/integration_test.rs b/tests/integration_test.rs index c66724f4..35f24ca9 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -43,7 +43,7 @@ async fn package_json() { let package_json = resolution.package_json().unwrap(); assert_eq!(package_json.name.as_ref().unwrap(), "name"); assert_eq!(package_json.r#type, Some(ModuleType::Module)); - assert!(matches!(package_json.side_effects, Some(_))); + assert!(package_json.side_effects.is_some()); } #[cfg(feature = "package_json_raw_json_api")]