1#[cfg(feature = "download-to-file")]
2mod download_to_file;
3#[cfg(feature = "download-to-file")]
4pub use self::download_to_file::download_to_file;
5
6#[cfg(feature = "drop-remove-path")]
7mod drop_remove_path;
8#[cfg(feature = "drop-remove-path")]
9pub use self::drop_remove_path::DropRemovePath;
10
11#[cfg(feature = "download-to-path")]
12mod download_to_path;
13#[cfg(feature = "download-to-path")]
14pub use self::download_to_path::download_to_path;
15
16#[cfg(feature = "arc-anyhow-error")]
17mod arc_anyhow_error;
18#[cfg(feature = "arc-anyhow-error")]
19pub use self::arc_anyhow_error::ArcAnyhowError;
20
21use std::ffi::OsStr;
22use std::ffi::OsString;
23use std::path::Path;
24use std::path::PathBuf;
25
26pub fn push_extension<S>(path: &mut PathBuf, extension: S)
28where
29 S: AsRef<OsStr>,
30{
31 let extension = extension.as_ref();
32
33 if path.extension().is_none() {
35 path.set_extension(extension);
36 return;
37 }
38
39 let mut path_string = OsString::from(std::mem::take(path));
45 path_string.reserve(extension.len() + 1);
46 path_string.push(".");
47 path_string.push(extension);
48 std::mem::swap(path, &mut path_string.into());
49}
50
51pub fn with_push_extension<P, S>(path: P, extension: S) -> PathBuf
53where
54 P: AsRef<Path>,
55 S: AsRef<OsStr>,
56{
57 let path = path.as_ref();
58 let extension = extension.as_ref();
59
60 if path.extension().is_none() {
62 return path.with_extension(extension);
63 }
64
65 let mut path_string = OsString::from(path);
68 path_string.reserve(extension.len() + 1);
69 path_string.push(".");
70 path_string.push(extension);
71 PathBuf::from(path_string)
72}
73
74pub fn try_create_dir<P>(path: P) -> std::io::Result<bool>
81where
82 P: AsRef<Path>,
83{
84 match std::fs::create_dir(path) {
85 Ok(()) => Ok(true),
86 Err(error) if error.kind() == std::io::ErrorKind::AlreadyExists => Ok(false),
87 Err(error) => Err(error),
88 }
89}
90
91pub fn try_remove_dir<P>(path: P) -> std::io::Result<bool>
98where
99 P: AsRef<Path>,
100{
101 match std::fs::remove_dir(path) {
102 Ok(()) => Ok(true),
103 Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(false),
104 Err(error) => Err(error),
105 }
106}
107
108#[cfg(test)]
109mod test {
110 use super::*;
111
112 #[test]
113 fn push_path_extension_works() {
114 let base_path = PathBuf::from("file.txt");
115 let extension = "part";
116 let with_push_extension_path = with_push_extension(&base_path, extension);
117 let mut push_extension_path = base_path;
118 push_extension(&mut push_extension_path, extension);
119
120 let expected = Path::new("file.txt.part");
121 assert!(with_push_extension_path == expected);
122 assert!(push_extension_path == expected);
123
124 let base_path = PathBuf::from("file");
125 let extension = "part";
126 let with_push_extension_path = with_push_extension(&base_path, extension);
127 let mut push_extension_path = base_path;
128 push_extension(&mut push_extension_path, extension);
129
130 let expected = Path::new("file.part");
131 assert!(with_push_extension_path == expected);
132 assert!(push_extension_path == expected);
133 }
134
135 #[test]
136 fn try_create_dir_works() {
137 let path = "test_tmp/try_create_dir";
138
139 std::fs::create_dir_all("test_tmp").expect("failed to create tmp dir");
140
141 try_remove_dir(path).expect("failed to remove dir");
142 assert!(try_create_dir(path).expect("failed to create dir"));
143 assert!(!try_create_dir(path).expect("failed to create dir"));
144 assert!(try_remove_dir(path).expect("failed to remove dir"));
145 assert!(!try_remove_dir(path).expect("failed to remove dir"));
146 }
147}