From 0c30e065b678d41d8932b3bf0926608cfa15a7ac Mon Sep 17 00:00:00 2001 From: metamuffin Date: Tue, 10 Jan 2023 08:44:06 +0100 Subject: first listing --- src/library.rs | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 9 deletions(-) (limited to 'src/library.rs') diff --git a/src/library.rs b/src/library.rs index 576ed77..e4c7fe6 100644 --- a/src/library.rs +++ b/src/library.rs @@ -1,23 +1,96 @@ -use anyhow::Ok; +use std::{fs::File, path::PathBuf, str::FromStr, sync::Arc}; + +use anyhow::{bail, Context, Ok}; +use chashmap::CHashMap; +use serde::{Deserialize, Serialize}; pub struct Library { - path: String, - tree: LibNode, + path: PathBuf, + cache: CHashMap, // TODO } +#[derive(Debug, Clone)] pub enum LibNode { - Directory(LibDirectory), - Item(LibItem), + Directory(Arc), + Item(Arc), +} + +#[derive(Debug, Clone)] +pub struct LibDirectory { + pub path: PathBuf, + pub child_nodes: Vec, + pub data: LibDirectoryData, +} + +#[derive(Debug, Clone)] +pub struct LibItem { + pub data: LibItemData, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct LibDirectoryData { + pub name: String, } -pub struct LibDirectory {} -pub struct LibItem {} +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct LibItemData {} impl Library { pub fn open(path: &str) -> anyhow::Result { Ok(Self { - path: path.to_string(), - tree: , + path: PathBuf::from_str(path).unwrap(), + cache: CHashMap::new(), }) } + pub fn root(&self) -> anyhow::Result> { + LibNode::from_path(self.path.clone()) + } + pub fn nested(&self, path: &str) -> anyhow::Result> { + let mut n = self.root()?; + if path == "" { + return Ok(n); + } + for seg in path.split("/") { + n = n.get_directory()?.get_child(seg)? + } + Ok(n) + } +} +impl LibDirectory { + pub fn get_child(&self, p: &str) -> anyhow::Result> { + if p.contains("..") || p.starts_with("/") { + bail!("no! dont do that.") + } + let path = self.path.join(p); + // if !path.exists() {bail!("does not exist");} + LibNode::from_path(path) + } +} +impl LibNode { + pub fn get_directory(&self) -> anyhow::Result<&LibDirectory> { + match self { + LibNode::Directory(d) => Ok(d), + LibNode::Item(_) => bail!("not a directory"), + } + } + pub fn from_path(path: PathBuf) -> anyhow::Result> { + if path.is_dir() { + let mpath = path.join("directory.json"); + let data: LibDirectoryData = + serde_json::from_reader(File::open(mpath).context("metadata missing")?)?; + let child_nodes = path.read_dir()?.map(|e| e.unwrap().path()).collect(); + Ok(LibNode::Directory(Arc::new(LibDirectory { + path, + child_nodes, + data, + })) + .into()) + } else if path.is_file() { + let mpath = path.clone().with_extension(".metadata.json"); + let data: LibItemData = serde_json::from_reader(File::open(mpath)?)?; + Ok(LibNode::Item(Arc::new(LibItem { data })).into()) + } else { + bail!("did somebody really put a fifo or socket in the library?!") + } + } } -- cgit v1.2.3-70-g09d2