mirror of
https://github.com/YGGverse/titanit.git
synced 2026-03-31 17:15:30 +00:00
initial commit
This commit is contained in:
parent
c6f6ec7ba4
commit
86e07f08c7
7 changed files with 408 additions and 0 deletions
85
src/storage.rs
Normal file
85
src/storage.rs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
use anyhow::{bail, Result};
|
||||
use std::{
|
||||
fs::{create_dir_all, remove_file, rename, File},
|
||||
path::{PathBuf, MAIN_SEPARATOR},
|
||||
thread,
|
||||
time::{Duration, SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
const TMP_SUFFIX: &str = ".tmp";
|
||||
|
||||
pub struct Item {
|
||||
pub file: File,
|
||||
pub path: PathBuf,
|
||||
// pub id: u64,
|
||||
}
|
||||
|
||||
impl Item {
|
||||
// Constructors
|
||||
|
||||
pub fn create(directory: &str) -> Result<Self> {
|
||||
loop {
|
||||
// generate file id from current unix time
|
||||
let id = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
|
||||
|
||||
// build optimized fs path:
|
||||
// add directory separator after every digit to keep up to 10 files per directory
|
||||
let path = PathBuf::from(format!(
|
||||
"{}{MAIN_SEPARATOR}{}{TMP_SUFFIX}",
|
||||
directory.trim_end_matches(MAIN_SEPARATOR),
|
||||
id.to_string().chars().fold(String::new(), |mut acc, c| {
|
||||
if !acc.is_empty() {
|
||||
acc.push(MAIN_SEPARATOR);
|
||||
}
|
||||
acc.push(c);
|
||||
acc
|
||||
})
|
||||
));
|
||||
|
||||
// recursively create directories
|
||||
// * parent directory is expected
|
||||
create_dir_all(path.parent().unwrap())?;
|
||||
|
||||
// build `Self`
|
||||
match File::create_new(&path) {
|
||||
// make sure slot is not taken (by another thread)
|
||||
Ok(file) => {
|
||||
return Ok(Self {
|
||||
file,
|
||||
path,
|
||||
// id
|
||||
});
|
||||
}
|
||||
Err(_) => {
|
||||
println!("[warning] Could not init location: {:?}", path.to_str());
|
||||
// find free slot after some delay..
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
||||
/// Take object processed, commit its changes
|
||||
pub fn commit(self) -> Result<()> {
|
||||
match self.path.to_str() {
|
||||
Some(old) => match old.strip_suffix(TMP_SUFFIX) {
|
||||
Some(new) => Ok(rename(old, new)?),
|
||||
None => bail!("Invalid TMP suffix"), // | panic
|
||||
},
|
||||
None => bail!("Invalid Item path"), // | panic
|
||||
}
|
||||
}
|
||||
|
||||
/// Cleanup object relationships
|
||||
pub fn delete(self) -> Result<()> {
|
||||
Ok(remove_file(self.path)?)
|
||||
}
|
||||
|
||||
// Getters
|
||||
|
||||
/* @TODO implement short links handle without slash
|
||||
pub fn alias(&self, relative: &str) -> String {} */
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue