restart from scratch
parent
cb6bce2ba5
commit
2e63947569
|
|
@ -1,79 +1 @@
|
|||
local fs = require("filesystem")
|
||||
|
||||
local FileTree = {}
|
||||
function FileTree:new(iterator)
|
||||
local file_tree = {
|
||||
iterator = iterator,
|
||||
filters = {}
|
||||
}
|
||||
setmetatable(file_tree, self)
|
||||
self.__index = self
|
||||
return file_tree
|
||||
end
|
||||
|
||||
function directory(path_or_dir)
|
||||
if type(path_or_dir) == "string" then
|
||||
return FileTree:new(fs.directory_source(path_or_dir))
|
||||
end
|
||||
if path_or_dir.path ~= nil then
|
||||
return FileTree:new(fs.directory_source(path_or_dir.path))
|
||||
end
|
||||
error("Invalid type for directory")
|
||||
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 _,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 is_file(entry)
|
||||
return entry:is_dir()
|
||||
end
|
||||
|
||||
function starts_with(prefix)
|
||||
return function(entry)
|
||||
return entry.path:find("^"..prefix)
|
||||
end
|
||||
end
|
||||
|
||||
function contains(infix)
|
||||
return function(entry)
|
||||
return entry.path:find(infix)
|
||||
end
|
||||
end
|
||||
|
||||
function does_not(predicate)
|
||||
return function(...) return not predicate(...) end
|
||||
end
|
||||
|
||||
function zip(source)
|
||||
print("would zip")
|
||||
for entry in source do
|
||||
print(entry.path)
|
||||
end
|
||||
end
|
||||
|
||||
local comic_dir = directory("/Users/kinch/Desktop/Rebuild World")
|
||||
comic_dir:filter(is_dir)
|
||||
|
||||
for chapter_dir in comic_dir do
|
||||
zip(directory(chapter_dir):filter(does_not(contains("._"))))
|
||||
end
|
||||
|
|
@ -1,16 +1,7 @@
|
|||
use crate::source::directory_source::DirectorySource;
|
||||
use mlua::prelude::*;
|
||||
|
||||
pub mod resources;
|
||||
pub mod sinks;
|
||||
pub mod source;
|
||||
fn directory_source(lua: &Lua, path: String) -> LuaResult<DirectorySource> {
|
||||
Ok(DirectorySource::from(path))
|
||||
}
|
||||
|
||||
#[mlua::lua_module]
|
||||
fn filesystem(lua: &Lua) -> LuaResult<LuaTable> {
|
||||
let exports = lua.create_table()?;
|
||||
exports.set("directory_source", lua.create_function(directory_source)?)?;
|
||||
Ok(exports)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
use std::ops::Deref;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub trait ResourceInputStream: std::io::Read {
|
||||
fn path(&self) -> PathBuf;
|
||||
}
|
||||
|
||||
pub type DynResourceInputStream = Box<dyn ResourceInputStream>;
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
pub mod input_stream;
|
||||
mod input_stream_filesystem;
|
||||
pub mod resource_filesystem;
|
||||
|
||||
use mlua::{MetaMethod, UserData, UserDataFields, UserDataMethods};
|
||||
use std::fs::FileType;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum ResourceType {
|
||||
Directory,
|
||||
RegularFile,
|
||||
}
|
||||
|
||||
pub trait Resource {
|
||||
fn path(&self) -> String;
|
||||
fn basename(&self) -> Option<String>;
|
||||
fn dirname(&self) -> Option<String>;
|
||||
fn extension(&self) -> Option<String>;
|
||||
fn stem(&self) -> Option<String>;
|
||||
fn file_type(&mut self) -> ResourceType;
|
||||
//noinspection RsSelfConvention
|
||||
fn is_dir(&mut self) -> bool {
|
||||
if let ResourceType::Directory = self.file_type() {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
//noinspection RsSelfConvention
|
||||
fn is_file(&mut self) -> bool {
|
||||
if let ResourceType::RegularFile = self.file_type() {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ResourceWrapper<ResType>(ResType);
|
||||
|
||||
impl<ResType: Resource> From<ResType> for ResourceWrapper<ResType> {
|
||||
fn from(value: ResType) -> Self {
|
||||
ResourceWrapper(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<ResType> Deref for ResourceWrapper<ResType> {
|
||||
type Target = ResType;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<Restype> DerefMut for ResourceWrapper<Restype> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<ResType: Resource> UserData for ResourceWrapper<ResType> {
|
||||
fn add_fields<'lua, F: UserDataFields<'lua, Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("file_name", |lua, this| Ok(this.basename()));
|
||||
fields.add_field_method_get("dirname", |lua, this| Ok(this.dirname()));
|
||||
fields.add_field_method_get("extension", |lua, this| Ok(this.extension()));
|
||||
fields.add_field_method_get("stem", |lua, this| Ok(this.stem()));
|
||||
fields.add_field_method_get("path", |lua, this| Ok(this.path()));
|
||||
}
|
||||
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_method_mut("is_dir", |lua, this, _: ()| Ok(this.is_dir()));
|
||||
methods.add_method_mut("is_file", |lua, this, _: ()| Ok(this.is_file()));
|
||||
methods.add_meta_method(MetaMethod::ToString, |lua, this, _: ()| Ok(this.path()))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
use crate::resources::{Resource, ResourceType};
|
||||
use std::fs::FileType;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub struct FilesystemResource {
|
||||
path: PathBuf,
|
||||
resource_type: Option<ResourceType>,
|
||||
}
|
||||
|
||||
impl From<PathBuf> for FilesystemResource {
|
||||
fn from(path: PathBuf) -> Self {
|
||||
FilesystemResource {
|
||||
path,
|
||||
resource_type: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Resource for FilesystemResource {
|
||||
fn path(&self) -> String {
|
||||
self.path.display().to_string()
|
||||
}
|
||||
|
||||
fn basename(&self) -> Option<String> {
|
||||
self.path
|
||||
.file_name()
|
||||
.and_then(|s| s.to_str())
|
||||
.map(|s| s.to_string())
|
||||
}
|
||||
|
||||
fn dirname(&self) -> Option<String> {
|
||||
self.path.parent().map(|p| p.display().to_string())
|
||||
}
|
||||
|
||||
fn extension(&self) -> Option<String> {
|
||||
self.path
|
||||
.extension()
|
||||
.and_then(|s| s.to_str())
|
||||
.map(|s| s.to_string())
|
||||
}
|
||||
|
||||
fn stem(&self) -> Option<String> {
|
||||
self.path
|
||||
.file_stem()
|
||||
.and_then(|s| s.to_str())
|
||||
.map(|s| s.to_string())
|
||||
}
|
||||
|
||||
fn file_type(&mut self) -> ResourceType {
|
||||
if let Some(resource_type) = self.resource_type {
|
||||
return resource_type;
|
||||
} else {
|
||||
let resource_type = self.path.metadata().unwrap().file_type().into();
|
||||
self.resource_type = Some(resource_type);
|
||||
resource_type
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<FileType> for ResourceType {
|
||||
fn from(file_type: FileType) -> Self {
|
||||
if file_type.is_file() {
|
||||
ResourceType::RegularFile
|
||||
} else {
|
||||
ResourceType::Directory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
use crate::resources::input_stream::DynResourceInputStream;
|
||||
use crate::resources::Resource;
|
||||
use mlua::{UserData, UserDataMethods};
|
||||
use std::path::PathBuf;
|
||||
|
||||
mod zip_sink;
|
||||
|
||||
pub trait ResourceSink {
|
||||
fn new(path: PathBuf) -> Self;
|
||||
fn add_file(&mut self, input: DynResourceInputStream);
|
||||
fn add_directory(&mut self, dirname: String);
|
||||
}
|
||||
|
||||
pub struct ResourceSinkWrapper<SinkType: ResourceSink>(SinkType);
|
||||
|
||||
impl<SinkType: ResourceSink> UserData for ResourceSinkWrapper<SinkType> {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_method_mut("add_file", |lua, this, resouce: DynResourceInputStream|)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
use crate::resources::input_stream::DynResourceInputStream;
|
||||
use crate::sinks::ResourceSink;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::ptr::write;
|
||||
use zip::ZipWriter;
|
||||
|
||||
pub struct ZipSink {
|
||||
writer: ZipWriter<File>,
|
||||
}
|
||||
|
||||
impl ResourceSink for ZipSink {
|
||||
fn new(path: PathBuf) -> Self {
|
||||
ZipSink {
|
||||
writer: ZipWriter::new(std::fs::File::create(path).expect("could not create file")),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_file(&mut self, mut input: DynResourceInputStream) {
|
||||
self.writer
|
||||
.start_file(input.path().display().to_string(), Default::default())
|
||||
.expect("error writing zip");
|
||||
std::io::copy(&mut input, &mut self.writer).expect("error writing zip");
|
||||
}
|
||||
|
||||
fn add_directory(&mut self, dirname: String) {
|
||||
todo!("implementing adding directory")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
use crate::resources::resource_filesystem::FilesystemResource;
|
||||
use crate::resources::ResourceWrapper;
|
||||
use crate::source::RessourceSource;
|
||||
use mlua::{MetaMethod, UserData, UserDataMethods};
|
||||
use std::fs::{read_dir, ReadDir};
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub struct DirectorySource {
|
||||
path: PathBuf,
|
||||
read_dir: ReadDir,
|
||||
}
|
||||
|
||||
impl From<String> for DirectorySource {
|
||||
fn from(path: String) -> Self {
|
||||
let path = PathBuf::from(path);
|
||||
let read_dir = std::fs::read_dir(&path).expect("could not read dir");
|
||||
DirectorySource { path, read_dir }
|
||||
}
|
||||
}
|
||||
|
||||
impl RessourceSource<FilesystemResource> for DirectorySource {
|
||||
fn root(&self) -> FilesystemResource {
|
||||
self.path.clone().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for DirectorySource {
|
||||
type Item = FilesystemResource;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.read_dir
|
||||
.next()
|
||||
.map(|entry| entry.expect("Could not read directory content").path())
|
||||
.map(|path| FilesystemResource::from(path))
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for DirectorySource {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(MetaMethod::ToString, |_, this, _: ()| {
|
||||
Ok(this.path.display().to_string())
|
||||
});
|
||||
methods.add_meta_method_mut(MetaMethod::Call, |_, this, _: ()| {
|
||||
Ok(this.next().map(|entry| ResourceWrapper::from(entry)))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
use crate::resources::Resource;
|
||||
|
||||
pub mod directory_source;
|
||||
pub trait RessourceSource<ResType: Resource>: Iterator {
|
||||
fn root(&self) -> ResType;
|
||||
}
|
||||
Loading…
Reference in New Issue