1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use std::{io, path::PathBuf};
use lunar_lib::{ask, error, info};
use crate::{config::common::CommonConfig, utils::list_dirs_to_string};
impl CommonConfig {
/// Sets your library directory to the input path after validation
///
/// The directory is invalid if:
/// - The library directory starts with a source
/// - Any source starts with the library directory
/// - The library directory is equal to any source
/// - The path is relative
///
/// # Errors
///
/// Errors when sources or the library fail to canonicalize via `std::path::Path::canonicalize()`
/// Paths that do not exist on the file system are not canonicalized
pub fn set_library_directory(&mut self, path: impl Into<PathBuf>) -> io::Result<&mut Self> {
let path = path.into();
let library_dir = self.library_dir.as_ref();
if Some(&path) == library_dir {
info!(
"The library directory is already set to '{}'",
path.display()
);
return Ok(self);
}
if !self.valid_library_dir(&path)? {
error!(
"Could not set the library directory to '{}': Path is not valid",
path.display()
);
return Ok(self);
}
self.library_dir = Some(path);
Ok(self)
}
/// Sets your sources to the input sources after validation
///
/// Sources are invalid if:
/// - The library directory starts with the source
/// - The source starts with the library directory
/// - The library directory and source are equal
/// - The source is a relative path
///
/// # Errors
///
/// Errors when sources or the library fail to canonicalize via `std::path::Path::canonicalize()`
/// Paths that do not exist on the file system are not canonicalized
pub fn set_library_sources(&mut self, paths: &[PathBuf]) -> io::Result<&mut Self> {
if paths.is_empty() {
self.source_dirs = Vec::new();
return Ok(self);
}
let validity_checked_paths: Vec<(PathBuf, bool)> = paths
.iter()
.map(|p| {
let is_valid = self.valid_source_dir(p)?;
Ok((p.clone(), is_valid))
})
.collect::<Result<Vec<_>, io::Error>>()?;
let validated: Vec<PathBuf> = validity_checked_paths
.iter()
.filter_map(|(source, valid)| if *valid { Some(source.clone()) } else { None })
.collect();
let invalidated: Vec<&PathBuf> = validity_checked_paths
.iter()
.filter_map(|(source, valid)| if *valid { None } else { Some(source) })
.collect();
let validated_string = list_dirs_to_string(&validated);
let invalidated_string = list_dirs_to_string(&invalidated);
if validated.is_empty() {
error!(
"Could not set source directories: All inputs are invalid:\n{invalidated_string}"
);
} else {
if !invalidated.is_empty() {
let confirm = ask!(
true,
"Invalid directories detected:\n{invalidated_string}\n\nWould you still like to set the valid source directories?:\n{validated_string}"
);
if !confirm.unwrap_or(false) {
return Ok(self);
}
}
info!("Sucessfully set the source directories to:\n{validated_string}");
self.source_dirs = validated;
}
Ok(self)
}
}