/ bin / fud / fud / src / util.rs
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  }