diff --git a/src/storage.rs b/src/storage.rs index fffe68d..bd0b4f5 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Error, Result}; +use anyhow::{anyhow, bail, Error, Result}; use std::{ fs::{create_dir_all, remove_file, rename, File}, path::{PathBuf, MAIN_SEPARATOR}, @@ -18,6 +18,35 @@ pub struct Item { impl Item { // Constructors + /// Build new `Self` from URL (request) + /// * e.g. 123 -> /directory/1/2/3 + pub fn from_url(url: &str, directory: &str) -> Result { + let s = match url.rfind('/') { + Some(pos) => match url.get(pos + 1..) { + Some(u) => u.parse::()?, + None => bail!("Invalid request"), + }, + None => bail!("ID not found"), + } + .to_string(); + let mut p = String::with_capacity(s.len()); + for (i, d) in s.chars().enumerate() { + if i > 0 { + p.push(MAIN_SEPARATOR) + } + p.push(d) + } + let path = PathBuf::from_str(&format!( + "{}{MAIN_SEPARATOR}{p}", + directory.trim_end_matches(MAIN_SEPARATOR), + ))?; + Ok(Self { + file: File::open(&path)?, + path, + }) + } + + /// Create new `Self` with unique pathname in the root `directory` pub fn create(directory: &str) -> Result { loop { // generate file id from current unix time @@ -83,12 +112,14 @@ impl Item { } } + /// Delete `Self`, cleanup FS pub fn delete(self) -> Result<()> { Ok(remove_file(self.path)?) } // Getters + /// Shared helper to build public URI pub fn to_uri(&self, directory: &str) -> String { self.path .to_str() @@ -96,7 +127,4 @@ impl Item { .replace(directory, "") .replace("/", "") } - - /* @TODO implement short links handle without slash - pub fn alias(&self, relative: &str) -> String {} */ }