diff --git a/lua/fs.example.lua b/lua/fs.example.lua index 0d27484..e6b38b5 100644 --- a/lua/fs.example.lua +++ b/lua/fs.example.lua @@ -1,13 +1,67 @@ local fs = require("filesystem") -local dirs = fs.directory("/Users/kinch/Desktop/Onepunch-Man") +local dirs = fs.directory("/Users/kinch/Desktop/Rebuild World") -for dir in dirs do - if dir:is_dir() then - print(dir) +local FileTree = {foo = "bar"} +function FileTree:new(iterator) + local file_tree = { + iterator = iterator, + filters = {} + } + setmetatable(file_tree, self) + self.__index = self + return file_tree +end + +function FileTree:filter(filter_fn) + table.insert(self.filters, filter_fn) + return self +end + +function FileTree:__call() + local next = self.iterator() + if next == nil then + return nil + end + + for k,filter in pairs(self.filters) do + if (not filter(next)) then + return self() + end + end + return next +end + +function is_dir(entry) + return entry:is_dir() +end + +function starts_with(prefix) + return function(entry) + return entry.path:find("^"..prefix) end end +function does_not(predicate) + return function(...) return not predicate(...) end +end + +local comic_dir = FileTree:new(fs.directory(".")) +comic_dir:filter(is_dir) + +for chapter_dir in comic_dir do + FileTree:new(fs.directory(chapter_dir)):filter(does_not(starts_with("./"))) + +end + +--for dir in dirs do +-- if dir:is_dir() then +-- for sub_dir in fs.directory(dir.path) do +-- print(sub_dir) +-- end +-- end +--end + --for dir in dirs do -- local files = dir:filter { -- exclude = function(file) diff --git a/lua_modules/filesystem/src/lib.rs b/lua_modules/filesystem/src/lib.rs index adc32da..afecf18 100644 --- a/lua_modules/filesystem/src/lib.rs +++ b/lua_modules/filesystem/src/lib.rs @@ -5,19 +5,12 @@ use mlua::prelude::*; fn directory(lua: &Lua, path: String) -> LuaResult { let read_dir = std::fs::read_dir(path).unwrap(); - Ok(DirectoryFileTreeIter { - read_dir, - filters: vec![], - }) + Ok(DirectoryFileTreeIter { read_dir }) } #[mlua::lua_module] fn filesystem(lua: &Lua) -> LuaResult { let exports = lua.create_table()?; - let file_types = lua.create_table()?; - file_types.set("Directory", DirectoryType)?; - file_types.set("File", RegularFileType)?; exports.set("directory", lua.create_function(directory)?)?; - exports.set("file_types", file_types)?; Ok(exports) } diff --git a/lua_modules/filesystem/src/types/file_tree.rs b/lua_modules/filesystem/src/types/file_tree.rs index b299d64..8b0d6c1 100644 --- a/lua_modules/filesystem/src/types/file_tree.rs +++ b/lua_modules/filesystem/src/types/file_tree.rs @@ -1,46 +1,35 @@ use crate::types::file_tree::ResourceType::{Directory, RegularFile}; -use mlua::{Function, MetaMethod, UserData, UserDataMethods}; +use mlua::{MetaMethod, UserData, UserDataFields, UserDataMethods}; use std::fs::{DirEntry, FileType, ReadDir}; use std::path::PathBuf; pub enum ResourceType { - Directory(DirectoryType), - RegularFile(RegularFileType), + Directory, + RegularFile, } -pub struct DirectoryType; -pub struct RegularFileType; - -impl UserData for DirectoryType {} -impl UserData for RegularFileType {} - impl From for ResourceType { fn from(file_type: FileType) -> Self { if file_type.is_file() { - RegularFile(RegularFileType) + RegularFile } else { - Directory(DirectoryType) + Directory } } } -pub struct DynResource(Box); -pub struct ResourceFilter { - pub filter_fn: Box bool>, -} - pub trait Resource { fn path(&self) -> String; fn file_type(&self) -> ResourceType; fn is_dir(&self) -> bool { - if let Directory(_dir) = self.file_type() { + if let Directory = self.file_type() { true } else { false } } fn is_file(&self) -> bool { - if let RegularFile(_dir) = self.file_type() { + if let RegularFile = self.file_type() { true } else { false @@ -64,7 +53,6 @@ pub trait FileTreeIter: Iterator {} pub struct DirectoryFileTreeIter { pub read_dir: ReadDir, - pub filters: Vec, } impl Iterator for DirectoryFileTreeIter { @@ -84,16 +72,13 @@ impl From for FileSystemResource { impl UserData for DirectoryFileTreeIter { fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { methods.add_meta_method_mut(MetaMethod::Call, |lua, dir_iter, _: ()| Ok(dir_iter.next())); - // methods.add_method_mut("filter", |lua, dir_iter, lua_filter_fn: Function| { - // let filter = ResourceFilter { - // filter_fn: Box::new(move |entry| lua_filter_fn.call(()).unwrap()), - // }; - // dir_iter.filters.push(filter); - // Ok(()) - // }) } } impl UserData for FileSystemResource { + fn add_fields<'lua, F: UserDataFields<'lua, Self>>(fields: &mut F) { + fields.add_field_method_get("path", |lua, fsr| Ok(fsr.path.display().to_string())) + } + fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { methods.add_meta_method(MetaMethod::ToString, |lua, fsr, _: ()| Ok(fsr.path())); methods.add_method("is_dir", |lua, fsr, _: ()| Ok(fsr.is_dir()));