leo_package/inputs/
directory.rs

1// Copyright (C) 2019-2024 Aleo Systems Inc.
2// This file is part of the Leo library.
3
4// The Leo library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// The Leo library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
16
17use leo_errors::{PackageError, Result};
18
19use std::{
20    borrow::Cow,
21    fs,
22    fs::ReadDir,
23    path::{Path, PathBuf},
24};
25
26pub static INPUTS_DIRECTORY_NAME: &str = "inputs/";
27
28pub struct InputsDirectory;
29
30impl InputsDirectory {
31    /// Creates a directory at the provided path with the default directory name.
32    pub fn create(path: &Path) -> Result<()> {
33        let mut path = Cow::from(path);
34        if path.is_dir() && !path.ends_with(INPUTS_DIRECTORY_NAME) {
35            path.to_mut().push(INPUTS_DIRECTORY_NAME);
36        }
37
38        fs::create_dir_all(&path).map_err(PackageError::failed_to_create_inputs_directory)?;
39        Ok(())
40    }
41
42    /// Returns a list of files in the input directory.
43    pub fn files(path: &Path) -> Result<Vec<PathBuf>> {
44        let mut path = path.to_owned();
45        path.push(INPUTS_DIRECTORY_NAME);
46
47        let directory = fs::read_dir(&path).map_err(PackageError::failed_to_read_inputs_directory)?;
48        let mut file_paths = Vec::new();
49        parse_file_paths(directory, &mut file_paths)?;
50
51        Ok(file_paths)
52    }
53}
54
55fn parse_file_paths(directory: ReadDir, file_paths: &mut Vec<PathBuf>) -> Result<()> {
56    for file_entry in directory {
57        let file_entry = file_entry.map_err(PackageError::failed_to_get_input_file_entry)?;
58        let file_path = file_entry.path();
59
60        // Verify that the entry is structured as a valid file or directory
61        let file_type = file_entry
62            .file_type()
63            .map_err(|e| PackageError::failed_to_get_input_file_type(file_path.as_os_str().to_owned(), e))?;
64        if file_type.is_dir() {
65            let directory = fs::read_dir(&file_path).map_err(PackageError::failed_to_read_inputs_directory)?;
66
67            parse_file_paths(directory, file_paths)?;
68            continue;
69        } else if !file_type.is_file() {
70            return Err(PackageError::invalid_input_file_type(file_path.as_os_str().to_owned(), file_type).into());
71        }
72
73        file_paths.push(file_path);
74    }
75
76    Ok(())
77}