diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..65326bb --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use nix \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9f97022..1eeadba 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -target/ \ No newline at end of file +target/ +.direnv \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 15bbf0f..6dcbe34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,3 +12,107 @@ dependencies = [ [[package]] name = "kosmora" version = "0.1.0" +dependencies = [ + "walkdir", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/arch.txt b/arch.txt new file mode 100644 index 0000000..e69de29 diff --git a/consumer/src/main.rs b/consumer/src/main.rs index 5d5e3b3..142d00b 100644 --- a/consumer/src/main.rs +++ b/consumer/src/main.rs @@ -6,4 +6,3 @@ fn main() { let example_path: &Path = &std::path::Path::new("."); example_path.to_kosmora_inode(); } - \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..02894a0 --- /dev/null +++ b/flake.lock @@ -0,0 +1,190 @@ +{ + "nodes": { + "alejandra": { + "inputs": { + "fenix": "fenix", + "flakeCompat": "flakeCompat", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1730688725, + "narHash": "sha256-g0SSfTWZ5mtMOpQic+eqq9sXMy1E/7yKxxfupZd9V4A=", + "owner": "kamadorueda", + "repo": "alejandra", + "rev": "2bb91e309ca99656addff5c74545acbf5813636d", + "type": "github" + }, + "original": { + "owner": "kamadorueda", + "ref": "3.1.0", + "repo": "alejandra", + "type": "github" + } + }, + "fenix": { + "inputs": { + "nixpkgs": [ + "alejandra", + "nixpkgs" + ], + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1730615655, + "narHash": "sha256-2HBR3zLn57LXKNRtxBb+O+uDqHM4n0pz51rPayMl4cg=", + "owner": "nix-community", + "repo": "fenix", + "rev": "efeb50e2535b17ffd4a135e6e3e5fd60a525180c", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "flake-compat": { + "locked": { + "lastModified": 1733328505, + "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", + "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", + "revCount": 69, + "type": "tarball", + "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.1.0/01948eb7-9cba-704f-bbf3-3fa956735b52/source.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz" + } + }, + "flakeCompat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1742889210, + "narHash": "sha256-hw63HnwnqU3ZQfsMclLhMvOezpM7RSB0dMAtD5/sOiw=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "698214a32beb4f4c8e3942372c694f40848b360d", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1736320768, + "narHash": "sha256-nIYdTAiKIGnFNugbomgBJR+Xv5F1ZQU+HfaBqJKroC0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4bc9c909d9ac828a039f288cf872d16d38185db8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "alejandra": "alejandra", + "flake-compat": "flake-compat", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay", + "utils": "utils" + } + }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1730555913, + "narHash": "sha256-KNHZUlqsEibg3YtfUyOFQSofP8hp1HKoY+laoesBxRM=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "f17a5bbfd0969ba2e63a74505a80e55ecb174ed9", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1743129211, + "narHash": "sha256-gE8t+U9miTwm2NYWS9dFY8H1/QB4ifaFDq1KdV9KEqo=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "f93da1d26ba9963f34f94a6872b67a7939699543", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..62c5dbf --- /dev/null +++ b/flake.nix @@ -0,0 +1,53 @@ +{ + description = "Kosmora - A space efficient virtual filesystem written in RUst."; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + utils.url = "github:numtide/flake-utils"; + rust-overlay.url = "github:oxalica/rust-overlay"; + flake-compat.url = "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"; + alejandra.url = "github:kamadorueda/alejandra/3.1.0"; + alejandra.inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = { + self, + nixpkgs, + utils, + rust-overlay, + alejandra, + ... + }: + { + overlays.default = final: prev: { + }; + } + // utils.lib.eachDefaultSystem ( + system: let + pkgs = import nixpkgs { + inherit system; + overlays = [ + self.overlays.default + (import rust-overlay) + ]; + }; + buildInputs = with pkgs; [ + pkg-config + ]; + in { + devShells.default = pkgs.mkShell { + name = "kosmora"; + nativeBuildInputs = with pkgs; [ + rust-bin.stable.latest.default + pkg-config + ]; + buildInputs = buildInputs; + shellHook = '' + export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${builtins.toString (pkgs.lib.makeLibraryPath buildInputs)}"; + echo "Rust version: $(rustc --version)"; + ''; + }; + + formatter = alejandra.packages.${system}.default; + } + ); +} diff --git a/kosmora/Cargo.toml b/kosmora/Cargo.toml index 941c56a..a740325 100644 --- a/kosmora/Cargo.toml +++ b/kosmora/Cargo.toml @@ -4,3 +4,4 @@ version = "0.1.0" edition = "2024" [dependencies] +walkdir = "2.5.0" diff --git a/kosmora/src/lib.rs b/kosmora/src/lib.rs index 10dd003..1b0b9dc 100644 --- a/kosmora/src/lib.rs +++ b/kosmora/src/lib.rs @@ -1,49 +1,59 @@ -use std::boxed::Box; +use std::{boxed::Box, fs, io::Seek, path, vec}; + +use walkdir::WalkDir; +#[derive(Debug)] pub struct KosmoraVfs { index: KosmoraIndex, - packages: Vec + packages: Vec, } +#[derive(Debug)] struct KosmoraIndex { - index: Vec + index: Vec, } +#[derive(Debug)] + struct KosmoraPackage { id: usize, - inode_index: KosmoraDirectory + inode_index: KosmoraDirectory, } +#[derive(Debug)] pub enum KosmoraINodeType { File(KosmoraFile), - Directory(KosmoraDirectory) + Directory(KosmoraDirectory), } +#[derive(Debug)] pub struct KosmoraFileMetadata { name: String, extension: Option, size: usize, } +#[derive(Debug)] pub struct KosmoraFile { metadata: KosmoraFileMetadata, - data: Vec + data: Vec, } - +#[derive(Debug)] pub struct KosmoraDirectory { name: String, parent: Option>, - children: Option> + children: Option>, } +#[derive(Debug)] pub struct KosmoraINode { - inode: KosmoraINodeType + inode: KosmoraINodeType, } impl KosmoraVfs { pub fn new() -> Self { KosmoraVfs { index: KosmoraIndex { index: Vec::new() }, - packages: Vec::new() + packages: Vec::new(), } } @@ -53,28 +63,60 @@ impl KosmoraVfs { } pub trait KosmoraINodeInteroperable { - fn collect_directory_children(&self) -> KosmoraINode; + fn collect_directory_children(&self) -> Vec; fn to_kosmora_inode(&self) -> KosmoraINode; } impl KosmoraINodeInteroperable for std::path::Path { - fn collect_directory_children(&self) -> KosmoraINode { - if !self.exists() || !self.is_dir() { - panic!("nuh uh that isnt allowed") + fn collect_directory_children(&self) -> Vec { + if !self.is_dir() {} + dbg!(self); + + let mut inodes: Vec = 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> { + + 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); } - dbg!(self); - match std::fs::File::open(&self) { - Ok(file) => { - todo!() - }, - Err(e) => { - eprintln!("{e}"); - todo!() - } - } + inodes } - + fn to_kosmora_inode(&self) -> KosmoraINode { if !self.exists() { panic!("Path does not exist"); @@ -82,32 +124,52 @@ 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(), + name: self + .components() + .last() + .unwrap() + .as_os_str() + .to_string_lossy() + .into(), parent: None, - children: Some(Box::new(self.collect_directory_children())), + children: Some(self.collect_directory_children()), }; - return KosmoraINode { inode: KosmoraINodeType::Directory(dir) }; - } + return KosmoraINode { + inode: KosmoraINodeType::Directory(dir), + }; + } if self.is_file() { - let meta = self.metadata() + let meta = self + .metadata() .map_err(|_| panic!("Failed to get metadata")) .ok() .expect("Failed to get metadata"); let file_metadata = KosmoraFileMetadata { name: String::from(self.file_name().unwrap().to_str().unwrap().to_string()), - extension: Some(self.file_name().unwrap().to_str().unwrap().split(".").last().unwrap().to_string()), + extension: Some( + self.file_name() + .unwrap() + .to_str() + .unwrap() + .split(".") + .last() + .unwrap() + .to_string(), + ), size: meta.len() as usize, }; - + let file = KosmoraFile { metadata: file_metadata, data: std::fs::read(self).unwrap(), }; - return KosmoraINode { inode: KosmoraINodeType::File(file) } + return KosmoraINode { + inode: KosmoraINodeType::File(file), + }; } panic!("Unsupported path type"); } -} \ No newline at end of file +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..3899c24 --- /dev/null +++ b/shell.nix @@ -0,0 +1,15 @@ +( + import + ( + let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + nodeName = lock.nodes.root.inputs.flake-compat; + in + fetchTarball { + url = lock.nodes.${nodeName}.locked.url or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.${nodeName}.locked.rev}.tar.gz"; + sha256 = lock.nodes.${nodeName}.locked.narHash; + } + ) + {src = ./.;} +) +.shellNix