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
146#[cfg(test)]
147mod tests {
148 use super::*;
149
150 const REMOTE_PATH_WINDOWS: &str = r"\\mynas\some\path";
151 const REMOTE_PATH_LINUX: &str = r"smb://mynas/some/path";
152 const LOCAL_PATH_LINUX: &str = r"/mnt/mynas/some/path";
153
154 #[test]
155 fn test_convert_unc() {
156 let res = convert_unc(REMOTE_PATH_WINDOWS, PathType::Linux).unwrap();
157 assert_eq!(res, REMOTE_PATH_LINUX);
158
159 let res = convert_unc(REMOTE_PATH_WINDOWS, PathType::Windows).unwrap();
160 assert_eq!(res, REMOTE_PATH_WINDOWS);
161
162 let res = convert_unc(REMOTE_PATH_LINUX, PathType::Windows).unwrap();
163 assert_eq!(res, REMOTE_PATH_WINDOWS);
164
165 let res = convert_unc(REMOTE_PATH_LINUX, PathType::Linux).unwrap();
166 assert_eq!(res, REMOTE_PATH_LINUX);
167
168 let invalid_path = "invalid-path";
169 let err = convert_unc(invalid_path, PathType::Linux).unwrap_err();
170 assert_eq!(err, Error::InvalidPathFormat);
171 }
172
173 #[test]
174 fn test_local_path() {
175 let res = local_path(REMOTE_PATH_WINDOWS).unwrap();
176 assert_eq!(res, LOCAL_PATH_LINUX);
177
178 let res = local_path(REMOTE_PATH_LINUX).unwrap();
179 assert_eq!(res, LOCAL_PATH_LINUX);
180 }
181
182 #[test]
183 fn test_local_path_invalid_data() {
184 let invalid_path = r"no-such-path";
185 let invalid_path2 = r"smb://";
186 let invalid_path3 = r"smb://aaa/bbb/ccc";
187 let invalid_path4 = r"\\";
188 let invalid_path5 = r"\\aaa\bbb\ccc";
189
190 let err = local_path(invalid_path).unwrap_err();
191 assert_eq!(err, Error::InvalidPathFormat);
192
193 let err = local_path(invalid_path2).unwrap_err();
194 assert_eq!(err, Error::LocalPathNotFound);
195
196 let err = local_path(invalid_path3).unwrap_err();
197 assert_eq!(err, Error::LocalPathNotFound);
198
199 let err = local_path(invalid_path4).unwrap_err();
200 assert_eq!(err, Error::LocalPathNotFound);
201
202 let err = local_path(invalid_path5).unwrap_err();
203 assert_eq!(err, Error::LocalPathNotFound);
204 }
205
206 #[test]
207 fn test_remote_path() {
208 let res = remote_path(LOCAL_PATH_LINUX, PathType::Windows).unwrap();
209 assert_eq!(res, REMOTE_PATH_WINDOWS);
210
211 let res = remote_path(LOCAL_PATH_LINUX, PathType::Linux).unwrap();
212 assert_eq!(res, REMOTE_PATH_LINUX);
213
214 let invalid_path = r"no-such-path";
215 let err = remote_path(invalid_path, PathType::Windows).unwrap_err();
216 assert_eq!(err, Error::RemotePathNotFound);
217 }
218}