Compare commits
1 Commits
main
...
be999d9086
| Author | SHA1 | Date | |
|---|---|---|---|
|
be999d9086
|
@@ -9,6 +9,7 @@ cfg_if! {
|
||||
pub mod auth_backend;
|
||||
pub mod redis;
|
||||
pub mod extract_field;
|
||||
pub mod random_path;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
36
src/util/random_path.rs
Normal file
36
src/util/random_path.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
/// Generates random paths for storing assets
|
||||
use rand::{rng, Rng};
|
||||
use std::ffi::OsStr;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Generate a random path for storing a new file
|
||||
/// The path will be in the format `base_path/XX/XXXXXXXXXX.extension`
|
||||
pub fn checked_random_path<P: Into<PathBuf>, E: AsRef<OsStr>>(
|
||||
base_path: P,
|
||||
extension: E,
|
||||
) -> PathBuf {
|
||||
let base_path: PathBuf = base_path.into();
|
||||
let mut rng = rng();
|
||||
|
||||
// Loop until we find a path that does not exist
|
||||
// If the existance check fails, we assume the path does not exist
|
||||
// since it is extremely unlikely to encounter a collision anyway
|
||||
loop {
|
||||
let random_bytes: [u8; 16] = rng.random();
|
||||
|
||||
let dir_part = format!("{:02x}", random_bytes[0]);
|
||||
let file_part = random_bytes[1..]
|
||||
.iter()
|
||||
.map(|byte| format!("{byte:02x}"))
|
||||
.collect::<String>();
|
||||
|
||||
let path = base_path
|
||||
.join(dir_part)
|
||||
.join(file_part)
|
||||
.with_extension(&extension);
|
||||
|
||||
if !path.try_exists().unwrap_or(false) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user