1pub mod fs {
4 use anyhow::{Context, Result};
5 use log::debug;
6 use std::fs;
7 use std::path::{Path, PathBuf};
8
9 #[allow(dead_code)]
11 pub fn copy_dir_recursive(src: &Path, dst: &Path) -> Result<()> {
12 debug!("Copying directory from {src:?} to {dst:?}");
13
14 if !dst.exists() {
16 fs::create_dir_all(dst)
17 .with_context(|| format!("Failed to create directory: {dst:?}"))?;
18 }
19
20 for entry in
22 fs::read_dir(src).with_context(|| format!("Failed to read directory: {src:?}"))?
23 {
24 let entry =
25 entry.with_context(|| format!("Failed to read directory entry in: {src:?}"))?;
26
27 let src_path = entry.path();
28 let dst_path = dst.join(entry.file_name());
29
30 if src_path.is_dir() {
31 copy_dir_recursive(&src_path, &dst_path)?;
33 } else {
34 fs::copy(&src_path, &dst_path)
36 .with_context(|| format!("Failed to copy {src_path:?} to {dst_path:?}"))?;
37 }
38 }
39
40 Ok(())
41 }
42
43 #[allow(dead_code)]
45 pub fn find_files_with_extension(dir: &Path, extension: &str) -> Result<Vec<PathBuf>> {
46 let mut result = Vec::new();
47
48 if !dir.exists() || !dir.is_dir() {
49 return Ok(result);
50 }
51
52 for entry in walkdir::WalkDir::new(dir) {
53 let entry =
54 entry.with_context(|| format!("Failed to read directory entry in: {dir:?}"))?;
55
56 let path = entry.path();
57
58 if path.is_file() && path.extension().and_then(|ext| ext.to_str()) == Some(extension) {
59 result.push(path.to_owned());
60 }
61 }
62
63 Ok(result)
64 }
65}
66
67pub mod crypto {
68 #[allow(dead_code)]
70 pub fn random_id() -> String {
71 use std::time::{SystemTime, UNIX_EPOCH};
72
73 let now = SystemTime::now()
74 .duration_since(UNIX_EPOCH)
75 .expect("Time went backwards")
76 .as_nanos();
77
78 format!("{now:x}")
79 }
80}