AppPath
Create paths relative to your executable for truly portable applications.
๐ฏ The Problem
When building applications that need to access files (configs, templates, data), you typically have two choices:
-
System directories (
~/.config/,%APPDATA%, etc.) - Great for installed apps, but...- Requires installation
- Spreads files across the system
- Hard to backup/move
- Needs admin rights on some systems
-
Hardcoded paths - Simple but brittle and non-portable
โจ The Solution
AppPath creates paths relative to your executable location, enabling truly portable applications where everything stays together.
use AppPath;
// These paths are automatically relative to your executable
let config = try_new?;
let templates = try_new?;
let data = try_new?;
// Check if files exist, create directories, etc.
if !config.exists
๐ Why Choose AppPath?
vs. Standard Library (std::env::current_dir())
// โ Brittle - depends on where user runs the program
let config = current_dir?.join;
// โ
Reliable - always relative to your executable
let config = try_new?;
vs. System Directories (directories crate)
// โ Scattered across the system
use ProjectDirs;
let proj_dirs = from.unwrap;
let config = proj_dirs.config_dir.join; // ~/.config/MyApp/config.toml
// โ
Everything together with your app
let config = try_new?; // ./config.toml (next to exe)
vs. Manual Path Joining
// โ Verbose and error-prone
let exe_path = current_exe?;
let exe_dir = exe_path.parent.ok_or?;
let config = exe_dir.join;
// โ
Clean and simple
let config = try_new?;
๐ Perfect For
- Portable applications that travel on USB drives
- Development tools that should work anywhere
- Corporate environments where you can't install software
- Containerized applications with predictable layouts
- Embedded systems with simple file structures
- Quick prototypes that need simple file access
๐ ๏ธ Features
- โ Zero dependencies - Lightweight and fast
- โ Cross-platform - Works on Windows, Linux, macOS
- โ
Simple API - Just
AppPath::try_new()and you're done - โ
Full
Pathcompatibility - ImplementsAsRef<Path>,Display, etc. - โ
Ergonomic conversions -
TryFrom<&str>,TryFrom<String>support - โ
Testing support - Override base directory with
with_base() - โ
Directory creation - Built-in
create_dir_all() - โ Well tested - Comprehensive test suite
๐ Quick Start
Add to your Cargo.toml:
[]
= "0.1"
use AppPath;
use fs;
Alternative Creation Methods
For ergonomic conversions from strings, use TryFrom:
use AppPath;
use TryFrom;
// Primary constructor - clear that it can fail
let config = try_new?;
// From string literals using TryFrom
let data = try_from?;
// From String values
let filename = "cache.json".to_string;
let cache = try_from?;
// From String references
let path_string = "logs/app.log".to_string;
let logs = try_from?;
// All methods give you the same functionality
assert_eq!;
๐๏ธ Application Structure
Your portable application structure becomes:
myapp.exe # Your executable
โโโ config.toml # AppPath::try_new("config.toml")
โโโ templates/ # AppPath::try_new("templates")
โ โโโ email.html
โ โโโ report.html
โโโ data/ # AppPath::try_new("data")
โ โโโ cache.db
โโโ logs/ # AppPath::try_new("logs")
โโโ app.log
๐งช Testing Support
Override the base directory for testing:
๐ Common Usage Patterns
Replace hardcoded paths:
// Instead of brittle hardcoded paths
let config = from; // Depends on working directory
// Use AppPath for reliable, portable paths
let config = try_new?; // Always relative to executable
Replace manual path construction:
// Instead of verbose manual construction
let exe = current_exe?;
let exe_dir = exe.parent.unwrap;
let config = exe_dir.join;
// Use AppPath for clean, simple code
let config = try_new?;
๐ License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
AppPath: Keep it simple, keep it together. ๐ฏ