starting with filetree

develop
Kinch 2023-09-17 20:12:38 +02:00
parent 7fc57fce47
commit f17bc694cc
3 changed files with 70 additions and 38 deletions

View File

@ -1,13 +1,67 @@
local fs = require("filesystem") 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 local FileTree = {foo = "bar"}
if dir:is_dir() then function FileTree:new(iterator)
print(dir) 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
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 --for dir in dirs do
-- local files = dir:filter { -- local files = dir:filter {
-- exclude = function(file) -- exclude = function(file)

View File

@ -5,19 +5,12 @@ use mlua::prelude::*;
fn directory(lua: &Lua, path: String) -> LuaResult<DirectoryFileTreeIter> { fn directory(lua: &Lua, path: String) -> LuaResult<DirectoryFileTreeIter> {
let read_dir = std::fs::read_dir(path).unwrap(); let read_dir = std::fs::read_dir(path).unwrap();
Ok(DirectoryFileTreeIter { Ok(DirectoryFileTreeIter { read_dir })
read_dir,
filters: vec![],
})
} }
#[mlua::lua_module] #[mlua::lua_module]
fn filesystem(lua: &Lua) -> LuaResult<LuaTable> { fn filesystem(lua: &Lua) -> LuaResult<LuaTable> {
let exports = lua.create_table()?; 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("directory", lua.create_function(directory)?)?;
exports.set("file_types", file_types)?;
Ok(exports) Ok(exports)
} }

View File

@ -1,46 +1,35 @@
use crate::types::file_tree::ResourceType::{Directory, RegularFile}; 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::fs::{DirEntry, FileType, ReadDir};
use std::path::PathBuf; use std::path::PathBuf;
pub enum ResourceType { pub enum ResourceType {
Directory(DirectoryType), Directory,
RegularFile(RegularFileType), RegularFile,
} }
pub struct DirectoryType;
pub struct RegularFileType;
impl UserData for DirectoryType {}
impl UserData for RegularFileType {}
impl From<FileType> for ResourceType { impl From<FileType> for ResourceType {
fn from(file_type: FileType) -> Self { fn from(file_type: FileType) -> Self {
if file_type.is_file() { if file_type.is_file() {
RegularFile(RegularFileType) RegularFile
} else { } else {
Directory(DirectoryType) Directory
} }
} }
} }
pub struct DynResource(Box<dyn Resource>);
pub struct ResourceFilter {
pub filter_fn: Box<dyn Fn(DynResource) -> bool>,
}
pub trait Resource { pub trait Resource {
fn path(&self) -> String; fn path(&self) -> String;
fn file_type(&self) -> ResourceType; fn file_type(&self) -> ResourceType;
fn is_dir(&self) -> bool { fn is_dir(&self) -> bool {
if let Directory(_dir) = self.file_type() { if let Directory = self.file_type() {
true true
} else { } else {
false false
} }
} }
fn is_file(&self) -> bool { fn is_file(&self) -> bool {
if let RegularFile(_dir) = self.file_type() { if let RegularFile = self.file_type() {
true true
} else { } else {
false false
@ -64,7 +53,6 @@ pub trait FileTreeIter<RES: Resource>: Iterator<Item = RES> {}
pub struct DirectoryFileTreeIter { pub struct DirectoryFileTreeIter {
pub read_dir: ReadDir, pub read_dir: ReadDir,
pub filters: Vec<ResourceFilter>,
} }
impl Iterator for DirectoryFileTreeIter { impl Iterator for DirectoryFileTreeIter {
@ -84,16 +72,13 @@ impl From<DirEntry> for FileSystemResource {
impl UserData for DirectoryFileTreeIter { impl UserData for DirectoryFileTreeIter {
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { 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_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 { 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) { fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
methods.add_meta_method(MetaMethod::ToString, |lua, fsr, _: ()| Ok(fsr.path())); methods.add_meta_method(MetaMethod::ToString, |lua, fsr, _: ()| Ok(fsr.path()));
methods.add_method("is_dir", |lua, fsr, _: ()| Ok(fsr.is_dir())); methods.add_method("is_dir", |lua, fsr, _: ()| Ok(fsr.is_dir()));