refac: create utilty functions for core functionality

This commit is contained in:
lily 2025-03-29 16:54:19 -04:00
parent d3942a512c
commit 16b505f5cf
Signed by: lily
GPG key ID: 601F3263FBCBC4B9
2 changed files with 129 additions and 86 deletions

View file

@ -1,5 +1,8 @@
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)]
pub struct KosmoraVfs {
@ -18,33 +21,33 @@ struct KosmoraPackage {
inode_index: KosmoraDirectory,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum KosmoraINodeType {
File(KosmoraFile),
Directory(KosmoraDirectory),
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct KosmoraFileMetadata {
name: String,
extension: Option<String>,
size: usize,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct KosmoraFile {
metadata: KosmoraFileMetadata,
data: Vec<u8>,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct KosmoraDirectory {
name: String,
parent: Option<Box<KosmoraDirectory>>,
children: Option<Vec<KosmoraINode>>,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct KosmoraINode {
inode: KosmoraINodeType,
}
@ -65,56 +68,13 @@ impl KosmoraVfs {
pub trait KosmoraINodeInteroperable {
fn collect_directory_children(&self) -> Vec<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 {
fn collect_directory_children(&self) -> Vec<KosmoraINode> {
if !self.is_dir() {}
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
tree::collect_physical_directory_children(self)
}
fn to_kosmora_inode(&self) -> KosmoraINode {
@ -123,31 +83,36 @@ impl KosmoraINodeInteroperable for std::path::Path {
}
if self.is_dir() {
let dir = KosmoraDirectory {
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),
};
return create_kosmora_directory(self, None, Some(collect_physical_directory_children(self)));
}
if self.is_file() {
let meta = self
.metadata()
.map_err(|_| panic!("Failed to get metadata"))
.ok()
.expect("Failed to get metadata");
return create_kosmora_file(self, Some(Box::new(self.parent().unwrap().to_kosmora_directory())));
}
panic!("Unsupported path type");
}
let file_metadata = KosmoraFileMetadata {
name: String::from(self.file_name().unwrap().to_str().unwrap().to_string()),
fn to_kosmora_directory(&self) -> KosmoraDirectory {
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(
self.file_name()
.unwrap()
@ -156,20 +121,21 @@ impl KosmoraINodeInteroperable for std::path::Path {
.split(".")
.last()
.unwrap()
.to_string(),
.into(),
),
size: meta.len() as usize,
};
let file = KosmoraFile {
metadata: file_metadata,
data: std::fs::read(self).unwrap(),
};
return KosmoraINode {
inode: KosmoraINodeType::File(file),
};
size: self.metadata().unwrap().len() as usize,
},
data: fs::read(self).unwrap(),
}
}
}
impl KosmoraDirectory {
fn with_children(&self, children: Vec<KosmoraINode>) -> KosmoraDirectory {
KosmoraDirectory {
name: self.name.clone(),
parent: self.parent.clone(),
children: Some(children),
}
panic!("Unsupported path type");
}
}

77
src/tree.rs Normal file
View 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),
}
}