std_macro_extensions/path/
macro.rs

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
/// Combines multiple paths into a single valid path, handling overlapping slashes.
///
/// - Removes trailing slashes from the base path.
/// - Removes leading slashes from subsequent paths to avoid duplication.
/// - Supports multiple path segments for flexible usage.
///
/// # Parameters
/// - `base`: The base path as a string slice. It serves as the starting point for the combined path.
/// - `sub_path`: One or more subsequent paths as string slices. These are appended to the base path in order.
///
/// # Returns
/// - `String`: The resulting combined path as a `String`, with platform-specific separators and cleaned of redundant slashes.
///
/// # Example
/// ```
/// use std_macro_extensions::*;
///
/// let combined_path: String = join_paths!("/home/", "/user/", "/documents", "file.txt");
/// assert_eq!(combined_path, "/home/user/documents/file.txt");
/// let another_path: String = join_paths!("C:/", "/Program Files", "App");
/// assert_eq!(another_path, "C:/Program Files/App");
/// ```
#[macro_export]
macro_rules! join_paths {
    ($base:expr, $($sub_path:expr),+) => {{
        let mut path = PathBuf::from($base.trim_end_matches(['/', '\\'].as_ref()));
        if cfg!(target_os = "windows") {
            if path.is_dir() && path.to_string_lossy().ends_with(":") {
                path.push("/");
            }
        }
        $(
            let clean_sub_path = $sub_path.trim_start_matches(['/', '\\'].as_ref());
            path.push(clean_sub_path);
        )+
        path.to_string_lossy().replace("\\", "/")
    }};
}