common_datasource/
util.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15pub fn find_dir_and_filename(path: &str) -> (String, Option<String>) {
16    if path.is_empty() {
17        ("/".to_string(), None)
18    } else if path.ends_with('/') {
19        (path.to_string(), None)
20    } else if let Some(idx) = path.rfind('/') {
21        (
22            path[..idx + 1].to_string(),
23            Some(path[idx + 1..].to_string()),
24        )
25    } else {
26        ("/".to_string(), Some(path.to_string()))
27    }
28}
29
30#[cfg(test)]
31mod tests {
32
33    use url::Url;
34
35    use super::*;
36
37    #[test]
38    fn test_parse_uri() {
39        struct Test<'a> {
40            uri: &'a str,
41            expected_path: &'a str,
42            expected_schema: &'a str,
43        }
44
45        let tests = [
46            Test {
47                uri: "s3://bucket/to/path/",
48                expected_path: "/to/path/",
49                expected_schema: "s3",
50            },
51            Test {
52                uri: "fs:///to/path/",
53                expected_path: "/to/path/",
54                expected_schema: "fs",
55            },
56            Test {
57                uri: "fs:///to/path/file",
58                expected_path: "/to/path/file",
59                expected_schema: "fs",
60            },
61        ];
62        for test in tests {
63            let parsed_uri = Url::parse(test.uri).unwrap();
64            assert_eq!(parsed_uri.path(), test.expected_path);
65            assert_eq!(parsed_uri.scheme(), test.expected_schema);
66        }
67    }
68
69    #[cfg(not(windows))]
70    #[test]
71    fn test_parse_path_and_dir() {
72        let parsed = Url::from_file_path("/to/path/file").unwrap();
73        assert_eq!(parsed.path(), "/to/path/file");
74
75        let parsed = Url::from_directory_path("/to/path/").unwrap();
76        assert_eq!(parsed.path(), "/to/path/");
77    }
78
79    #[cfg(windows)]
80    #[test]
81    fn test_parse_path_and_dir() {
82        let parsed = Url::from_file_path("C:\\to\\path\\file").unwrap();
83        assert_eq!(parsed.path(), "/C:/to/path/file");
84
85        let parsed = Url::from_directory_path("C:\\to\\path\\").unwrap();
86        assert_eq!(parsed.path(), "/C:/to/path/");
87    }
88
89    #[test]
90    fn test_find_dir_and_filename() {
91        struct Test<'a> {
92            path: &'a str,
93            expected_dir: &'a str,
94            expected_filename: Option<String>,
95        }
96
97        let tests = [
98            Test {
99                path: "to/path/",
100                expected_dir: "to/path/",
101                expected_filename: None,
102            },
103            Test {
104                path: "to/path/filename",
105                expected_dir: "to/path/",
106                expected_filename: Some("filename".into()),
107            },
108            Test {
109                path: "/to/path/filename",
110                expected_dir: "/to/path/",
111                expected_filename: Some("filename".into()),
112            },
113            Test {
114                path: "/",
115                expected_dir: "/",
116                expected_filename: None,
117            },
118            Test {
119                path: "filename",
120                expected_dir: "/",
121                expected_filename: Some("filename".into()),
122            },
123            Test {
124                path: "",
125                expected_dir: "/",
126                expected_filename: None,
127            },
128        ];
129
130        for test in tests {
131            let (path, filename) = find_dir_and_filename(test.path);
132            assert_eq!(test.expected_dir, path);
133            assert_eq!(test.expected_filename, filename)
134        }
135    }
136}