Implement walk_dir and more robust globbing
This commit is contained in:
parent
2964ebbe1b
commit
db4faea821
44
Cargo.lock
generated
44
Cargo.lock
generated
@ -691,6 +691,19 @@ version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
|
||||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.4.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"bstr",
|
||||
"log",
|
||||
"regex-automata 0.4.9",
|
||||
"regex-syntax 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.4.10"
|
||||
@ -1032,12 +1045,13 @@ name = "lb"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"derive_more",
|
||||
"glob",
|
||||
"globset",
|
||||
"luaffi",
|
||||
"luajit",
|
||||
"sysexits",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1579,6 +1593,15 @@ version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.26"
|
||||
@ -2070,6 +2093,16 @@ dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.1"
|
||||
@ -2121,6 +2154,15 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
|
@ -9,15 +9,15 @@ repository.workspace = true
|
||||
|
||||
[features]
|
||||
task = ["tokio/rt", "tokio/time"]
|
||||
fs = ["tokio/fs", "dep:glob"]
|
||||
fs = ["tokio/fs", "dep:walkdir", "dep:globset"]
|
||||
net = ["tokio/net"]
|
||||
glob = ["dep:glob"]
|
||||
|
||||
[dependencies]
|
||||
derive_more = { version = "2.0.1", features = ["full"] }
|
||||
glob = { version = "0.3.2", optional = true }
|
||||
globset = { version = "0.4.16", optional = true }
|
||||
luaffi = { path = "../luaffi" }
|
||||
luajit = { path = "../luajit" }
|
||||
sysexits = "0.9.0"
|
||||
thiserror = "2.0.12"
|
||||
tokio = { version = "1.45.1" }
|
||||
walkdir = { version = "2.5.0", optional = true }
|
||||
|
@ -14,7 +14,7 @@
|
||||
//! See [`lb_fslib`] for items exported by this library.
|
||||
use derive_more::From;
|
||||
use luaffi::{cdef, metatype};
|
||||
use std::time::SystemTime;
|
||||
use std::{path::PathBuf, time::SystemTime};
|
||||
use thiserror::Error;
|
||||
|
||||
/// Errors that can be thrown by this library.
|
||||
@ -26,12 +26,12 @@ pub enum Error {
|
||||
/// I/O error.
|
||||
#[error("{0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
/// Glob error.
|
||||
/// Walk directory error.
|
||||
#[error("{0}")]
|
||||
Glob(#[from] glob::GlobError),
|
||||
Walk(#[from] walkdir::Error),
|
||||
/// Glob pattern error.
|
||||
#[error("{0}")]
|
||||
GlobPattern(#[from] glob::PatternError),
|
||||
Glob(#[from] globset::Error),
|
||||
}
|
||||
|
||||
type Result<T> = std::result::Result<T, Error>;
|
||||
@ -77,8 +77,26 @@ impl lb_fslib {
|
||||
Ok(std::fs::read_dir(path)?.into())
|
||||
}
|
||||
|
||||
pub extern "Lua-C" fn glob(&self, pattern: &str) -> Result<lb_glob_paths> {
|
||||
Ok(glob::glob(pattern)?.into())
|
||||
pub extern "Lua-C" fn walk_dir(&self, path: &str) -> lb_walk_dir {
|
||||
walkdir::WalkDir::new(path).into_iter().into()
|
||||
}
|
||||
|
||||
pub extern "Lua-C" fn glob(&self, pattern: &str) -> Result<lb_glob_dir> {
|
||||
self.glob_dir(".", pattern)
|
||||
}
|
||||
|
||||
pub extern "Lua-C" fn glob_dir(&self, path: &str, pattern: &str) -> Result<lb_glob_dir> {
|
||||
let prefix = PathBuf::from(path);
|
||||
let iter = walkdir::WalkDir::new(path).min_depth(1).into_iter();
|
||||
let matcher = globset::GlobSet::builder()
|
||||
.add(globset::Glob::new(pattern)?)
|
||||
.build()?;
|
||||
|
||||
Ok(lb_glob_dir {
|
||||
iter,
|
||||
matcher,
|
||||
prefix,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -300,19 +318,86 @@ impl lb_file_perms {
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator that yields paths from the filesystem that match a particular pattern.
|
||||
/// Iterator for recursively descending into a directory.
|
||||
#[derive(Debug, From)]
|
||||
#[cdef]
|
||||
pub struct lb_glob_paths(#[opaque] glob::Paths);
|
||||
pub struct lb_walk_dir(#[opaque] walkdir::IntoIter);
|
||||
|
||||
#[metatype]
|
||||
impl lb_glob_paths {
|
||||
impl lb_walk_dir {
|
||||
#[call]
|
||||
pub extern "Lua-C" fn next(&mut self) -> Result<Option<String>> {
|
||||
Ok(self
|
||||
.0
|
||||
.next()
|
||||
.transpose()?
|
||||
.map(|s| s.to_string_lossy().into()))
|
||||
pub extern "Lua-C" fn next(&mut self) -> Result<Option<lb_walk_dir_entry>> {
|
||||
Ok(self.0.next().transpose()?.map(Into::into))
|
||||
}
|
||||
}
|
||||
|
||||
/// Entry inside of a directory on the filesystem obtained from [`lb_walk_dir`].
|
||||
#[derive(Debug, From)]
|
||||
#[cdef]
|
||||
pub struct lb_walk_dir_entry(#[opaque] walkdir::DirEntry);
|
||||
|
||||
#[metatype]
|
||||
impl lb_walk_dir_entry {
|
||||
pub extern "Lua-C" fn path(&self) -> String {
|
||||
self.0.path().to_string_lossy().into()
|
||||
}
|
||||
|
||||
pub extern "Lua-C" fn name(&self) -> String {
|
||||
self.0.file_name().to_string_lossy().into()
|
||||
}
|
||||
|
||||
pub extern "Lua-C" fn r#type(&self) -> lb_file_type {
|
||||
self.0.file_type().into()
|
||||
}
|
||||
|
||||
pub extern "Lua-C" fn metadata(&self) -> Result<lb_file_meta> {
|
||||
Ok(self.0.metadata()?.into())
|
||||
}
|
||||
|
||||
pub extern "Lua-C" fn is_symlink(&self) -> bool {
|
||||
self.0.path_is_symlink()
|
||||
}
|
||||
|
||||
pub extern "Lua-C" fn depth(&self) -> u32 {
|
||||
self.0.depth() as u32
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
pub extern "Lua-C" fn ino(&self) -> u64 {
|
||||
use walkdir::DirEntryExt;
|
||||
self.0.ino()
|
||||
}
|
||||
|
||||
#[tostring]
|
||||
pub extern "Lua" fn tostring(&self) -> String {
|
||||
self.path()
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator that yields paths from the filesystem that match a particular pattern.
|
||||
#[derive(Debug)]
|
||||
#[cdef]
|
||||
pub struct lb_glob_dir {
|
||||
#[opaque]
|
||||
iter: walkdir::IntoIter,
|
||||
#[opaque]
|
||||
matcher: globset::GlobSet,
|
||||
#[opaque]
|
||||
prefix: PathBuf,
|
||||
}
|
||||
|
||||
#[metatype]
|
||||
impl lb_glob_dir {
|
||||
#[call]
|
||||
pub extern "Lua-C" fn next(&mut self) -> Result<Option<lb_walk_dir_entry>> {
|
||||
while let Some(res) = self.iter.next() {
|
||||
let entry = res?;
|
||||
let path = entry.path().strip_prefix(&self.prefix).unwrap();
|
||||
if self.matcher.is_match(path) {
|
||||
return Ok(Some(entry.into()));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user