cdp_html_shot/browser/temp_dir.rs
1use std::fs;
2use chrono::Local;
3use rand::{thread_rng, Rng};
4use std::path::{Path, PathBuf};
5use anyhow::{Context, Result};
6
7#[derive(Debug)]
8pub(crate) struct CustomTempDir {
9 path: PathBuf,
10 is_cleaned: bool,
11}
12
13impl Drop for CustomTempDir {
14 fn drop(&mut self) {
15 if !self.is_cleaned {
16 let _ = self.cleanup();
17 }
18 }
19}
20
21impl CustomTempDir {
22 pub(crate) fn new(base_path: impl AsRef<Path>, prefix: &str) -> Result<Self> {
23 let base_path = base_path.as_ref();
24
25 fs::create_dir_all(base_path)
26 .context("Failed to create base directory")?;
27
28 let unique_name = generate_unique_name(prefix);
29 let full_path = base_path.join(unique_name);
30
31 fs::create_dir(&full_path)
32 .context("Failed to create temporary directory")?;
33
34 Ok(Self { path: full_path, is_cleaned: false })
35 }
36
37 pub(crate) fn path(&self) -> &Path {
38 &self.path
39 }
40
41 pub(crate) fn cleanup(&mut self) -> Result<()> {
42 if self.is_cleaned {
43 return Ok(());
44 }
45
46 fs::remove_dir_all(&self.path)
47 .context("Failed to clean up temporary directory")?;
48
49 self.is_cleaned = true;
50 Ok(())
51 }
52}
53
54fn generate_unique_name(prefix: &str) -> String {
55 let timestamp = Local::now().format("%Y%m%d_%H%M%S");
56 let random: String = thread_rng()
57 .sample_iter(&rand::distributions::Alphanumeric)
58 .take(8)
59 .map(char::from)
60 .collect();
61 format!("{prefix}_{timestamp}_{random}")
62}