Skip to main content

manycastr/cli/
utils.rs

1use log::{error, warn};
2use std::error::Error;
3use std::fs;
4use std::fs::File;
5use std::path::Path;
6
7/// Validate the provided path for writing permissions.
8/// # Arguments
9/// * `path_str` - Path to validate
10///
11/// # Returns
12/// * Ok(()) if the path is valid and writable, Err with a message otherwise
13///
14/// # Panics
15/// * If unable to get path metadata
16/// * If unable to create or remove file/directory
17pub fn validate_path_perms(path_str: &String) -> Result<(), Box<dyn Error>> {
18    let path = Path::new(path_str);
19    let is_dir = path_str.ends_with('/') || path.is_dir();
20
21    // If user provided a file
22    if !is_dir {
23        if path.exists() {
24            if fs::metadata(path)
25                .expect("Unable to get path metadata")
26                .permissions()
27                .readonly()
28            {
29                error!("[CLI] Lacking write permissions for file {path_str}");
30                return Err("Lacking write permissions".into());
31            } else {
32                warn!("[CLI] Overwriting existing file {path_str} when measurement is done");
33            }
34        } else {
35            // File does not yet exist, create it to verify permissions
36            File::create(path)
37                .expect("Unable to create output file")
38                .sync_all()
39                .expect("Unable to sync file");
40            fs::remove_file(path).expect("Unable to remove file");
41        }
42    } else {
43        // User provided a directory
44        if path.exists() {
45            if !path.is_dir() {
46                error!("[CLI] Path is already a file, exiting");
47                return Err("Cannot make dir, file with name already exists.".into());
48            } else if fs::metadata(path)
49                .expect("Unable to get path metadata")
50                .permissions()
51                .readonly()
52            {
53                error!("[CLI] Lacking write permissions for directory {path_str}");
54                return Err("Path is not writable".into());
55            }
56        } else {
57            // Attempt creating path to verify permissions
58            fs::create_dir_all(path).expect("Unable to create output directory");
59        }
60    }
61    Ok(())
62}