fud/
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
19use smol::{
20    fs::{self, File},
21    stream::StreamExt,
22};
23use std::{
24    collections::HashSet,
25    path::{Path, PathBuf},
26};
27
28pub use darkfi::geode::hash_to_string;
29use darkfi::Result;
30
31pub 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
51pub 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)]
68pub enum FileSelection {
69    All,
70    Set(HashSet<PathBuf>),
71}
72
73impl 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}