util.rs
1 /* This file is part of DarkFi (https://dark.fi) 2 * 3 * Copyright (C) 2020-2025 Dyne.org foundation 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU Affero General Public License as 7 * published by the Free Software Foundation, either version 3 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Affero General Public License for more details. 14 * 15 * You should have received a copy of the GNU Affero General Public License 16 * along with this program. If not, see <https://www.gnu.org/licenses/>. 17 */ 18 19 use smol::{ 20 fs::{self, File}, 21 stream::StreamExt, 22 }; 23 use std::{ 24 collections::HashSet, 25 path::{Path, PathBuf}, 26 }; 27 28 pub use darkfi::geode::hash_to_string; 29 use darkfi::Result; 30 31 pub async fn get_all_files(dir: &Path) -> Result<Vec<(PathBuf, u64)>> { 32 let mut files = Vec::new(); 33 34 let mut entries = fs::read_dir(dir).await.unwrap(); 35 36 while let Some(entry) = entries.try_next().await.unwrap() { 37 let path = entry.path(); 38 39 if path.is_dir() { 40 files.append(&mut Box::pin(get_all_files(&path)).await?); 41 } else { 42 let metadata = fs::metadata(&path).await?; 43 let file_size = metadata.len(); 44 files.push((path, file_size)); 45 } 46 } 47 48 Ok(files) 49 } 50 51 pub async fn create_all_files(files: &[PathBuf]) -> Result<()> { 52 for file_path in files.iter() { 53 if !file_path.exists() { 54 if let Some(dir) = file_path.parent() { 55 fs::create_dir_all(dir).await?; 56 } 57 File::create(&file_path).await?; 58 } 59 } 60 61 Ok(()) 62 } 63 64 /// An enum to represent a set of files, where you can use `All` if you want 65 /// all files without having to specify all of them. 66 /// We could use an `Option<HashSet<PathBuf>>`, but this is more explicit. 67 #[derive(Clone, Debug)] 68 pub enum FileSelection { 69 All, 70 Set(HashSet<PathBuf>), 71 } 72 73 impl FromIterator<PathBuf> for FileSelection { 74 fn from_iter<I: IntoIterator<Item = PathBuf>>(iter: I) -> Self { 75 let paths: HashSet<PathBuf> = iter.into_iter().collect(); 76 FileSelection::Set(paths) 77 } 78 }