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
14pub(crate) struct TempFile;
16
17impl TempFile {
18 pub fn new_name() -> PathBuf {
20 let mut temp_dir = env::temp_dir();
21
22 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 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}