app-path
Create portable applications that keep files together with the executable.
Simple, zero-dependency library for creating portable applications where configuration, data, and executable stay together as a deployable unit.
use app_path;
// Files relative to your executable - not current directory!
let config = app_path!; // → /path/to/exe/config.toml
let database = app_path!; // → /path/to/exe/data/users.db
// Acts just like std::path::Path
if config.exists
// Environment override magic for deployment ✨
let logs = app_path!;
// → Uses LOG_PATH if set, otherwise /path/to/exe/logs/app.log
database.create_parents?; // Creates data/ directory if it doesn't exist
Why Choose AppPath?
| Approach | Problem | AppPath Solution |
|---|---|---|
current_dir() |
Depends on where user runs program | ✅ Always relative to executable |
| System directories | Scatters files across system | ✅ Self-contained, portable |
| Hardcoded paths | Breaks when moved | ✅ Works anywhere |
Features
- 🚀 Zero dependencies - Only standard library
- ✨ Ergonomic macro - Clean syntax with
app_path! - 🌍 Cross-platform - Windows, Linux, macOS
- ⚡ High performance - Static caching, minimal allocations
- 🔧 Flexible deployment - Environment overrides
- 🛡️ Thread-safe - Concurrent access safe
- 📦 Portable - Entire app moves as one unit
API Overview
The app_path! Macro (Recommended)
use app_path;
// Simple paths
let config = app_path!;
// → /path/to/exe/config.toml
let database = app_path!;
// → /path/to/exe/data/users.db
// Environment variable overrides for deployment
let logs = app_path!;
// → Uses LOG_PATH if set, otherwise /path/to/exe/logs/app.log
let cache = app_path!;
// → Uses CACHE_DIR if set, otherwise /path/to/exe/cache
// Custom override logic with block expression
let data_dir = app_path!;
// → Uses DATA_DIR, then XDG_DATA_HOME/myapp, finally /path/to/exe/data
// Function-based override (great for XDG support)
let config_dir = app_path!;
// → /home/user/.config/myapp (Linux) or /path/to/exe/config (fallback)
// Simple override with optional value
let config = app_path!;
// → Uses CONFIG_PATH if set, otherwise /path/to/exe/config.toml
// Variable capturing in complex expressions
let version = "1.0";
let versioned_cache = app_path!;
// → /path/to/exe/cache-1.0
let temp_with_env = app_path!;
// → Uses TEMP_DIR if set, otherwise /path/to/exe/temp-1.0
// Directory creation with clear intent
logs.create_parents?; // Creates logs/ for the file
app_path!.create_dir?; // Creates temp/ directory itself
Fallible try_app_path! Macro (Libraries)
For libraries or applications requiring explicit error handling:
use ;
// Returns Result<AppPath, AppPathError> instead of panicking
let config = try_app_path!?;
// → Ok(/path/to/exe/config.toml) or Err(AppPathError)
let database = try_app_path!?;
// → Ok with DATABASE_PATH or default path, or Err(AppPathError)
// Variable capturing with error handling
let version = "1.0";
let versioned_cache = try_app_path!?;
// → Ok(/path/to/exe/cache-1.0) or Err(AppPathError)
let temp_with_env = try_app_path!?;
// → Ok with TEMP_DIR or default path, or Err(AppPathError)
// Same syntax, graceful error handling
match try_app_path!
// → Either creates logs/ directory or prints error message
Constructor API (Alternative)
use AppPath;
let config = new;
// → /path/to/exe/config.toml (panics on system failure)
let database = with_override;
// → Uses DB_PATH if set, otherwise /path/to/exe/data/users.db
// For libraries requiring fallible behavior
let config = try_new?;
// → Ok(/path/to/exe/config.toml) or Err(AppPathError)
Real-World Examples
Configuration Management
use app_path;
CLI Tool with File Management
use app_path;
Deployment Flexibility
use app_path;
// Same binary, different environments:
// Development: uses "./config/app.toml"
// Production: CONFIG_PATH="/etc/myapp/config.toml" overrides to absolute path
let config = app_path!;
// Conditional deployment paths
let logs = if cfg! else ;
Directory Creation
AppPath provides intuitive methods with clear intent:
create_parents()- Creates parent directories for file pathscreate_dir()- Creates the path as a directory
use app_path;
// Preparing to write files
let log_file = app_path!;
log_file.create_parents?; // Creates logs/ directory
write?;
// Creating directories
let cache_dir = app_path!;
cache_dir.create_dir?; // Creates cache/ directory
Path Resolution
- Relative paths → executable directory:
"config.toml"→./config.toml - Absolute paths → used as-is:
"/etc/app.conf"→/etc/app.conf - Environment overrides → replace default when set
Error Handling
AppPath panics only on extremely rare system failures (executable location undetermined). For libraries requiring explicit error handling:
use ;
match try_new
Ecosystem Integration
app-path integrates seamlessly with popular Rust path crates, letting you combine the best tools for your specific needs:
🔗 Popular Path Crate Compatibility
| Crate | Use Case | Integration Pattern |
|---|---|---|
camino |
UTF-8 path guarantees for web apps | Utf8PathBuf::try_from(app_path)? |
typed-path |
Cross-platform type-safe paths | WindowsPath::new(&app_path) |
pathos |
Advanced path operations & security | SecurePath::new(&app_path)? |
📝 Real-World Integration Examples
🌐 JSON-Safe Web Config (with camino)
use app_path;
use Utf8PathBuf;
let static_dir = app_path!;
let utf8_static = try_from?; // Direct conversion
// Guaranteed UTF-8 for JSON serialization
let config = json!;
🔨 Cross-Platform Build System (with typed-path)
use app_path;
use ;
let dist_dir = app_path!;
// Platform-specific paths with proper separators
let win_path = new; // Uses \ on Windows
let unix_path = new; // Uses / on Unix
🛡️ Secure Plugin System (with pathos)
use app_path;
use Path as SecurePath;
let plugin_dir = app_path!;
let plugin_path = new?.join?;
// Automatic path normalization and traversal protection
let safe_path = plugin_path.normalize?;
🛠 Migration-Friendly
Since AppPath implements Deref<Target=Path> and AsRef<Path>, you can:
- Drop-in replace existing
PathBufusage - Gradually adopt without rewriting entire codebases
- Mix and match with specialized path libraries
- Zero runtime overhead for standard path operations
Installation
[]
= "0.2"
Documentation
For comprehensive API documentation, examples, and guides, see docs.rs/app-path.