Expand description
§path_macro2
A cross-platform path construction macro for Rust that provides an intuitive syntax for building file paths while automatically handling platform-specific path separators.
§Features
- Dual syntax support: Use either slash (
/) or comma (,) separators - Cross-platform: Automatically uses correct path separators (
\on Windows,/on Unix-like systems) - Variable interpolation: Support for runtime variables and expressions
- Multiple segment types: Identifiers, dotted names, string literals, and expressions
- Zero dependencies: Lightweight macro-only implementation
§Installation
Add this to your Cargo.toml:
[dependencies]
path_macro2 = "0.1.1"§Usage
§Basic Syntax
The macro supports two equivalent syntaxes:
use path_macro2::path;
// Slash syntax
let path1 = path!(vendor / dll / windivert.c);
// Comma syntax
let path2 = path!(vendor, dll, windivert.c);
// Both produce the same result:
// Windows: "vendor\dll\windivert.c"
// Unix: "vendor/dll/windivert.c"§Supported Segment Types
§Identifiers and Dotted Names
let path = path!(vendor / include); // Simple identifiers
let file = path!(config / settings.json); // Dotted identifiers§String Literals (for spaces and special characters)
let path = path!("my folder" / "sub folder" / file.txt);
let docs = path!("Program Files" / "MyApp" / readme.md);§Variable Interpolation
let base = "vendor";
let version = "1.0";
// Variables wrapped in curly braces
let path = path!({base} / dll / file.txt);
let versioned = path!(libs / {format!("v{}", version)} / library.so);§Platform-Specific Examples
§Unix/Linux Absolute Paths
let abs_path = path!("/" / "usr" / "local" / "bin" / "myapp");
// Result: "/usr/local/bin/myapp"§Windows Paths
// Drive letter paths
let win_path = path!("C:\\" / "Program Files" / "MyApp" / "app.exe");
// Result: "C:\Program Files\MyApp\app.exe"
// UNC network paths
let unc_path = path!("\\\\" / "server" / "share" / "file.txt");
// Result: "\\server\share\file.txt"§Complex Examples
use path_macro2::path;
fn main() {
let project_root = std::env::var("PROJECT_ROOT").unwrap_or_else(|_| ".".to_string());
let build_type = "release";
// Mixed usage with variables and literals
let output_path = path!({project_root} / "target" / {build_type} / "myapp.exe");
// Handling paths with spaces
let data_path = path!({project_root} / "test data" / "sample files" / input.csv);
// Cross-platform configuration
let config_path = if cfg!(windows) {
path!("C:\\" / "ProgramData" / "MyApp" / config.toml)
} else {
path!("/" / "etc" / "myapp" / config.toml)
};
println!("Output: {}", output_path.display());
println!("Data: {}", data_path.display());
println!("Config: {}", config_path.display());
}§How It Works
The path! macro processes path segments and automatically:
- Converts identifiers to strings:
vendorbecomes"vendor" - Handles dotted identifiers:
file.txtbecomes"file.txt" - Preserves string literals:
"my folder"stays as-is - Evaluates expressions:
{base_path}evaluates the variable - Builds PathBuf: Uses
std::path::PathBuf::push()for proper platform handling
The result is always a std::path::PathBuf that uses the correct path
separators for the target platform.
§Comparison with Alternatives
| Method | Cross-platform | Readable | Variables | Compile-time |
|---|---|---|---|---|
path_macro2::path! | ✅ | ✅ | ✅ | ✅ |
std::path::Path::join() | ✅ | ❌ | ✅ | ❌ |
| String concatenation | ❌ | ❌ | ✅ | ❌ |
format!() with / | ❌ | ⚠️ | ✅ | ❌ |
§License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
§Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Macros§
- path
- Cross-platform path construction macro.