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}