refac: create utilty functions for core functionality
This commit is contained in:
parent
d3942a512c
commit
16b505f5cf
2 changed files with 129 additions and 86 deletions
138
src/lib.rs
138
src/lib.rs
|
@ -1,5 +1,8 @@
|
||||||
use std::{boxed::Box, fs, io::Seek, path, vec};
|
use std::{boxed::Box, fs, io::Seek, path, vec};
|
||||||
use walkdir::WalkDir;
|
use tree::{collect_physical_directory_children, create_kosmora_directory, create_kosmora_file};
|
||||||
|
use walkdir::{DirEntry, WalkDir};
|
||||||
|
|
||||||
|
mod tree;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct KosmoraVfs {
|
pub struct KosmoraVfs {
|
||||||
|
@ -18,33 +21,33 @@ struct KosmoraPackage {
|
||||||
inode_index: KosmoraDirectory,
|
inode_index: KosmoraDirectory,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum KosmoraINodeType {
|
pub enum KosmoraINodeType {
|
||||||
File(KosmoraFile),
|
File(KosmoraFile),
|
||||||
Directory(KosmoraDirectory),
|
Directory(KosmoraDirectory),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct KosmoraFileMetadata {
|
pub struct KosmoraFileMetadata {
|
||||||
name: String,
|
name: String,
|
||||||
extension: Option<String>,
|
extension: Option<String>,
|
||||||
size: usize,
|
size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct KosmoraFile {
|
pub struct KosmoraFile {
|
||||||
metadata: KosmoraFileMetadata,
|
metadata: KosmoraFileMetadata,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct KosmoraDirectory {
|
pub struct KosmoraDirectory {
|
||||||
name: String,
|
name: String,
|
||||||
parent: Option<Box<KosmoraDirectory>>,
|
parent: Option<Box<KosmoraDirectory>>,
|
||||||
children: Option<Vec<KosmoraINode>>,
|
children: Option<Vec<KosmoraINode>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct KosmoraINode {
|
pub struct KosmoraINode {
|
||||||
inode: KosmoraINodeType,
|
inode: KosmoraINodeType,
|
||||||
}
|
}
|
||||||
|
@ -65,56 +68,13 @@ impl KosmoraVfs {
|
||||||
pub trait KosmoraINodeInteroperable {
|
pub trait KosmoraINodeInteroperable {
|
||||||
fn collect_directory_children(&self) -> Vec<KosmoraINode>;
|
fn collect_directory_children(&self) -> Vec<KosmoraINode>;
|
||||||
fn to_kosmora_inode(&self) -> KosmoraINode;
|
fn to_kosmora_inode(&self) -> KosmoraINode;
|
||||||
|
fn to_kosmora_directory(&self) -> KosmoraDirectory;
|
||||||
|
fn to_kosmora_file(&self) -> KosmoraFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KosmoraINodeInteroperable for std::path::Path {
|
impl KosmoraINodeInteroperable for std::path::Path {
|
||||||
fn collect_directory_children(&self) -> Vec<KosmoraINode> {
|
fn collect_directory_children(&self) -> Vec<KosmoraINode> {
|
||||||
if !self.is_dir() {}
|
tree::collect_physical_directory_children(self)
|
||||||
dbg!(self);
|
|
||||||
|
|
||||||
let mut inodes: Vec<KosmoraINode> = vec![];
|
|
||||||
|
|
||||||
for entry in WalkDir::new(&self).into_iter().filter_map(|e| e.ok()) {
|
|
||||||
// println!("{}", entry.path().display());
|
|
||||||
let inode: KosmoraINode = match entry.path().is_file() {
|
|
||||||
true => {
|
|
||||||
let file = KosmoraFile {
|
|
||||||
metadata: KosmoraFileMetadata {
|
|
||||||
name: entry.file_name().to_string_lossy().into(),
|
|
||||||
extension: None,
|
|
||||||
size: entry.path().metadata().unwrap().len() as usize,
|
|
||||||
},
|
|
||||||
data: fs::read(entry.path()).unwrap(),
|
|
||||||
};
|
|
||||||
KosmoraINode {
|
|
||||||
inode: KosmoraINodeType::File(file),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false => {
|
|
||||||
fn read_upwards(path: &path::Path) -> Option<Box<KosmoraDirectory>> {
|
|
||||||
|
|
||||||
if let Some(parent) = path.parent() {
|
|
||||||
println!("{parent:#?}");
|
|
||||||
return read_upwards(parent)
|
|
||||||
} else {
|
|
||||||
return None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let dir = KosmoraDirectory {
|
|
||||||
name: entry.file_name().to_string_lossy().into(),
|
|
||||||
parent: read_upwards(entry.path()),
|
|
||||||
children: None,
|
|
||||||
};
|
|
||||||
KosmoraINode {
|
|
||||||
inode: KosmoraINodeType::Directory(dir),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inodes.push(inode);
|
|
||||||
}
|
|
||||||
|
|
||||||
inodes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_kosmora_inode(&self) -> KosmoraINode {
|
fn to_kosmora_inode(&self) -> KosmoraINode {
|
||||||
|
@ -123,31 +83,36 @@ impl KosmoraINodeInteroperable for std::path::Path {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.is_dir() {
|
if self.is_dir() {
|
||||||
let dir = KosmoraDirectory {
|
return create_kosmora_directory(self, None, Some(collect_physical_directory_children(self)));
|
||||||
name: self
|
|
||||||
.components()
|
|
||||||
.last()
|
|
||||||
.unwrap()
|
|
||||||
.as_os_str()
|
|
||||||
.to_string_lossy()
|
|
||||||
.into(),
|
|
||||||
parent: None,
|
|
||||||
children: Some(self.collect_directory_children()),
|
|
||||||
};
|
|
||||||
return KosmoraINode {
|
|
||||||
inode: KosmoraINodeType::Directory(dir),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.is_file() {
|
if self.is_file() {
|
||||||
let meta = self
|
return create_kosmora_file(self, Some(Box::new(self.parent().unwrap().to_kosmora_directory())));
|
||||||
.metadata()
|
}
|
||||||
.map_err(|_| panic!("Failed to get metadata"))
|
|
||||||
.ok()
|
panic!("Unsupported path type");
|
||||||
.expect("Failed to get metadata");
|
}
|
||||||
|
|
||||||
let file_metadata = KosmoraFileMetadata {
|
fn to_kosmora_directory(&self) -> KosmoraDirectory {
|
||||||
name: String::from(self.file_name().unwrap().to_str().unwrap().to_string()),
|
if !self.is_dir() {
|
||||||
|
panic!("Cannot convert file inode into Kosmora directory inode!");
|
||||||
|
}
|
||||||
|
|
||||||
|
KosmoraDirectory {
|
||||||
|
name: self.file_name().unwrap().to_string_lossy().into(),
|
||||||
|
parent: None,
|
||||||
|
children: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_kosmora_file(&self) -> KosmoraFile {
|
||||||
|
if !self.is_file() {
|
||||||
|
panic!("Cannot convert directory inode into Kosmora file inode!")
|
||||||
|
}
|
||||||
|
|
||||||
|
KosmoraFile {
|
||||||
|
metadata: KosmoraFileMetadata {
|
||||||
|
name: self.file_name().unwrap().to_string_lossy().into(),
|
||||||
extension: Some(
|
extension: Some(
|
||||||
self.file_name()
|
self.file_name()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -156,20 +121,21 @@ impl KosmoraINodeInteroperable for std::path::Path {
|
||||||
.split(".")
|
.split(".")
|
||||||
.last()
|
.last()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string(),
|
.into(),
|
||||||
),
|
),
|
||||||
size: meta.len() as usize,
|
size: self.metadata().unwrap().len() as usize,
|
||||||
};
|
},
|
||||||
|
data: fs::read(self).unwrap(),
|
||||||
let file = KosmoraFile {
|
}
|
||||||
metadata: file_metadata,
|
}
|
||||||
data: std::fs::read(self).unwrap(),
|
}
|
||||||
};
|
|
||||||
|
impl KosmoraDirectory {
|
||||||
return KosmoraINode {
|
fn with_children(&self, children: Vec<KosmoraINode>) -> KosmoraDirectory {
|
||||||
inode: KosmoraINodeType::File(file),
|
KosmoraDirectory {
|
||||||
};
|
name: self.name.clone(),
|
||||||
|
parent: self.parent.clone(),
|
||||||
|
children: Some(children),
|
||||||
}
|
}
|
||||||
panic!("Unsupported path type");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
77
src/tree.rs
Normal file
77
src/tree.rs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
use crate::{
|
||||||
|
KosmoraDirectory, KosmoraFile, KosmoraFileMetadata, KosmoraINode, KosmoraINodeInteroperable,
|
||||||
|
KosmoraINodeType,
|
||||||
|
};
|
||||||
|
use std::{boxed::Box, fs, path};
|
||||||
|
use walkdir::{DirEntry, WalkDir};
|
||||||
|
|
||||||
|
fn read_upwards(path: &path::Path) -> Option<Box<KosmoraDirectory>> {
|
||||||
|
if let Some(parent) = path.parent() {
|
||||||
|
return read_upwards(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn collect_physical_directory_children(path: &path::Path) -> Vec<KosmoraINode> {
|
||||||
|
if !path.is_dir() {
|
||||||
|
panic!("Cannot collect children of non-directory inode!");
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut inodes: Vec<KosmoraINode> = vec![];
|
||||||
|
|
||||||
|
for entry in WalkDir::new(path).into_iter().filter_map(|e| e.ok()) {
|
||||||
|
let inode: KosmoraINode = match entry.path().is_file() {
|
||||||
|
true => create_kosmora_file(
|
||||||
|
&entry.clone().into_path(),
|
||||||
|
Some(Box::new(
|
||||||
|
entry.path().parent().unwrap().to_kosmora_directory(),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
false => create_kosmora_directory(
|
||||||
|
&entry.clone().into_path(),
|
||||||
|
Some(Box::new(entry.path().parent().unwrap().to_kosmora_directory())),
|
||||||
|
Some(collect_physical_directory_children(entry.path()))
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
inodes.push(inode);
|
||||||
|
}
|
||||||
|
|
||||||
|
inodes
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn create_kosmora_file(
|
||||||
|
entry: &path::Path,
|
||||||
|
root: Option<Box<KosmoraDirectory>>,
|
||||||
|
) -> KosmoraINode {
|
||||||
|
let file = KosmoraFile {
|
||||||
|
metadata: KosmoraFileMetadata {
|
||||||
|
name: entry.file_name().unwrap().to_str().unwrap().to_string(),
|
||||||
|
extension: None,
|
||||||
|
size: entry.metadata().unwrap().len() as usize,
|
||||||
|
},
|
||||||
|
data: fs::read(entry).unwrap(),
|
||||||
|
};
|
||||||
|
|
||||||
|
KosmoraINode {
|
||||||
|
inode: KosmoraINodeType::File(file),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn create_kosmora_directory(
|
||||||
|
entry: &path::Path,
|
||||||
|
root: Option<Box<KosmoraDirectory>>,
|
||||||
|
content: Option<Vec<KosmoraINode>>,
|
||||||
|
) -> KosmoraINode {
|
||||||
|
let dir = KosmoraDirectory {
|
||||||
|
name: entry.file_name().unwrap().to_str().unwrap().to_string(),
|
||||||
|
// parent: read_upwards(entry.path()),
|
||||||
|
parent: root,
|
||||||
|
children: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
KosmoraINode {
|
||||||
|
inode: KosmoraINodeType::Directory(dir),
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue