1 个不稳定版本

0.2.0 2023 年 1 月 15 日

#1141文件系统


用于 ferrous-actions

BSD-3-Clause

28KB
565 行代码(不包括注释)

简单路径匹配

这是一个用于另一个项目的实用库。由于将其分解为单独的存储库可以更容易地运行测试,因此将其分解出来。

实现匹配模式与路径的能力

  • 文件系统分隔符在运行时指定。
  • 模式仅限于 glob 表达式语法,但只支持 *
  • * 不能匹配路径分隔符。
  • 单个组件中不能出现多个 *
  • 路径只能是 UTF-8 字符串 - 不支持字节切片或 OsStr
  • 可以测试路径是否是潜在匹配路径的前缀 - 这使得在搜索匹配时可以剪枝目录结构的遍历。
  • 没有直接支持与 std::path 匹配。
  • 没有能力使用模式迭代文件系统 - 它是一个针对 glob 模式的匹配器,而不是 glob 评估器。
  • 要匹配的路径的分隔符在运行时指定。
  • 模式中不允许出现 .. 实例 - 该库仅用于评估根路径下的相对路径。
  • 正在匹配的路径必须仅使用在 PathMatch 构造时指定的分隔符。

为什么有人想要一个如此多的限制的库?

此库被一个编译为 WASM(不使用 WASI)并在 node.js 上运行的项目使用,这意味着 std::path 的语义不清楚 - 没有文件系统访问,主机文件系统的属性仅在运行时才知道。

我找到的现有 glob 库与预期的主机文件系统的分隔符静态绑定,以及/或使用 std::path

此外,此库没有使用 regex crate,并且与 no_std 兼容。

使用示例

对多个路径进行匹配

// We use raw string literals here because we use backslash as a separator
let mut builder = PathMatchBuilder::new(r"\");
builder.add_pattern("./pdfs/*.pdf")?;
builder.add_pattern("./oggs/*.ogg")?;
builder.add_pattern("./folder_a")?;
builder.add_pattern("./folder_b/")?;
builder.add_pattern("./*/*/prefix.*")?;
let matcher = builder.build()?;

assert!(matcher.matches(r".\pdfs\test.pdf"));
assert!(matcher.matches(r"oggs\test.ogg"));

// Will match with or without a trailing slash
assert!(matcher.matches(r"folder_a"));
assert!(matcher.matches(r"folder_a\"));

// This does not match since trailing slashes are required if specified
assert!(!matcher.matches(r"folder_b"));
// But this one will
assert!(matcher.matches(r"folder_b\"));

// Wildcards are fine anywhere in a component, but we can only have one e.g. no *.*
assert!(matcher.matches(r"a\b\prefix.txt"));
Ok(())

依赖项

~1.5MB
~39K SLoC