tiny_web/sys/
file.rs

1use std::{
2    env,
3    path::PathBuf,
4    time::{SystemTime, UNIX_EPOCH},
5};
6
7use chrono::Local;
8use tokio::{fs::File, io::AsyncWriteExt};
9
10use crate::fnv1a_64;
11
12use super::log::Log;
13
14/// Empty struct for working temp file
15pub(crate) struct TempFile;
16
17impl TempFile {
18    /// Creates a unique new temporary file name
19    pub fn new_name() -> PathBuf {
20        let mut temp_dir = env::temp_dir();
21
22        // Generate a unique file name
23        let time = SystemTime::now();
24        let file_name = match time.duration_since(UNIX_EPOCH) {
25            Ok(epoch) => format!("tiny_{}_{}.tmp", epoch.as_secs(), epoch.subsec_nanos()),
26            Err(e) => {
27                Log::warning(2005, Some(e.to_string()));
28                format!("tiny_{}.tmp", fnv1a_64(Local::now().format("%Y.%m.%d %H:%M:%S%.9f").to_string().as_bytes()))
29            }
30        };
31        temp_dir.push(file_name);
32
33        temp_dir
34    }
35
36    /// Write data to the temporary file
37    pub async fn write(path: &PathBuf, data: &[u8]) -> Result<(), ()> {
38        let mut file = match File::create(path).await {
39            Ok(file) => file,
40            Err(e) => {
41                Log::warning(2002, Some(format!("{}. Error: {}", path.display(), e)));
42                return Err(());
43            }
44        };
45        let len = match file.write(data).await {
46            Ok(len) => len,
47            Err(e) => {
48                Log::warning(2003, Some(format!("{}. Error: {}", path.display(), e)));
49                return Err(());
50            }
51        };
52        if data.len() == len {
53            Ok(())
54        } else {
55            Log::warning(2004, Some(format!("{}. Written len: {} ({})", path.display(), len, data.len())));
56            Err(())
57        }
58    }
59}