1#![cfg_attr(test, allow(dead_code))]
8
9mod mounts;
10mod result;
11pub use crate::result::Error;
12pub use crate::result::Result;
13
14const OS_SEP_WINDOWS: &str = r"\";
15const OS_SEP_LINUX: &str = r"/";
16
17const UNC_PREFIX_WINDOWS: &str = r"\\";
18const UNC_PREFIX_LINUX: &str = r"smb://";
19
20#[derive(Debug, PartialEq)]
21pub enum PathType {
22 Windows,
23 Linux,
24}
25
26fn remote_path_to_intermediate(path: &str) -> Result<String> {
27 if path.starts_with(UNC_PREFIX_WINDOWS) {
28 Ok(path.replace(OS_SEP_WINDOWS, OS_SEP_LINUX))
29 } else if path.starts_with(UNC_PREFIX_LINUX) {
30 Ok(path[UNC_PREFIX_LINUX.len() - 2..].to_owned())
31 } else {
32 Err(Error::InvalidPathFormat)
33 }
34}
35
36fn intermediate_path_to_remote(path: &str, path_type: PathType) -> String {
37 match path_type {
38 PathType::Windows => path.replace(OS_SEP_LINUX, OS_SEP_WINDOWS),
39 PathType::Linux => UNC_PREFIX_LINUX[..UNC_PREFIX_LINUX.len() - 2].to_owned() + path,
40 }
41}
42
43pub fn convert_unc(path: &str, path_type: PathType) -> Result<String> {
71 let im_path = remote_path_to_intermediate(path)?;
72 Ok(intermediate_path_to_remote(&im_path, path_type))
73}
74
75pub fn local_path(path: &str) -> Result<String> {
110 let im_path = remote_path_to_intermediate(path)?;
111 mounts::cifs_local_path(&im_path)
112}
113
114pub fn remote_path(path: &str, path_type: PathType) -> Result<String> {
142 let im_path = mounts::cifs_remote_path(path)?;
143 Ok(intermediate_path_to_remote(&im_path, path_type))
144}
145
146pub fn version() -> &'static str {
148 env!("CARGO_PKG_VERSION")
149}
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154
155 const REMOTE_PATH_WINDOWS: &str = r"\\mynas\some\path";
156 const REMOTE_PATH_LINUX: &str = r"smb://mynas/some/path";
157 const LOCAL_PATH_LINUX: &str = r"/mnt/mynas/some/path";
158
159 #[test]
160 fn test_convert_unc() {
161 let res = convert_unc(REMOTE_PATH_WINDOWS, PathType::Linux).unwrap();
162 assert_eq!(res, REMOTE_PATH_LINUX);
163
164 let res = convert_unc(REMOTE_PATH_WINDOWS, PathType::Windows).unwrap();
165 assert_eq!(res, REMOTE_PATH_WINDOWS);
166
167 let res = convert_unc(REMOTE_PATH_LINUX, PathType::Windows).unwrap();
168 assert_eq!(res, REMOTE_PATH_WINDOWS);
169
170 let res = convert_unc(REMOTE_PATH_LINUX, PathType::Linux).unwrap();
171 assert_eq!(res, REMOTE_PATH_LINUX);
172
173 let invalid_path = "invalid-path";
174 let err = convert_unc(invalid_path, PathType::Linux).unwrap_err();
175 assert_eq!(err, Error::InvalidPathFormat);
176 }
177
178 #[test]
179 fn test_local_path() {
180 let res = local_path(REMOTE_PATH_WINDOWS).unwrap();
181 assert_eq!(res, LOCAL_PATH_LINUX);
182
183 let res = local_path(REMOTE_PATH_LINUX).unwrap();
184 assert_eq!(res, LOCAL_PATH_LINUX);
185 }
186
187 #[test]
188 fn test_local_path_invalid_data() {
189 let invalid_path = r"no-such-path";
190 let invalid_path2 = r"smb://";
191 let invalid_path3 = r"smb://aaa/bbb/ccc";
192 let invalid_path4 = r"\\";
193 let invalid_path5 = r"\\aaa\bbb\ccc";
194
195 let err = local_path(invalid_path).unwrap_err();
196 assert_eq!(err, Error::InvalidPathFormat);
197
198 let err = local_path(invalid_path2).unwrap_err();
199 assert_eq!(err, Error::LocalPathNotFound);
200
201 let err = local_path(invalid_path3).unwrap_err();
202 assert_eq!(err, Error::LocalPathNotFound);
203
204 let err = local_path(invalid_path4).unwrap_err();
205 assert_eq!(err, Error::LocalPathNotFound);
206
207 let err = local_path(invalid_path5).unwrap_err();
208 assert_eq!(err, Error::LocalPathNotFound);
209 }
210
211 #[test]
212 fn test_remote_path() {
213 let res = remote_path(LOCAL_PATH_LINUX, PathType::Windows).unwrap();
214 assert_eq!(res, REMOTE_PATH_WINDOWS);
215
216 let res = remote_path(LOCAL_PATH_LINUX, PathType::Linux).unwrap();
217 assert_eq!(res, REMOTE_PATH_LINUX);
218
219 let invalid_path = r"no-such-path";
220 let err = remote_path(invalid_path, PathType::Windows).unwrap_err();
221 assert_eq!(err, Error::RemotePathNotFound);
222 }
223}