Migration Guide: v0.4.0 → v0.5.0#
This guide will help you migrate from dir_spec v0.4.0 to v0.5.0.
Overview#
Version 0.5.0 removes the Dir struct and exposes all directory resolution functions at the module level. This change
simplifies the API and reduces redundant naming.
Breaking Changes#
Function Calls#
Before (v0.4.0):
use dir_spec::Dir;
let config = Dir::config_home();
let cache = Dir::cache_home();
let data = Dir::data_home();
After (v0.5.0):
use dir_spec::{config_home, cache_home, data_home};
// or
use dir_spec::*;
let config = config_home();
let cache = cache_home();
let data = data_home();
Import Changes#
Before (v0.4.0):
use dir_spec::Dir;
After (v0.5.0):
// Import specific functions you need
use dir_spec::{config_home, data_home, cache_home};
// Or import everything (not recommended for libraries)
use dir_spec::*;
// Or use fully qualified names
let config = dir_spec::config_home();
Complete Migration Examples#
Example 1: Configuration Management#
Before:
use dir_spec::Dir;
fn setup_config() -> Result<(), Box<dyn std::error::Error>> {
let config_dir = Dir::config_home()
.ok_or("Could not determine config directory")?;
let data_dir = Dir::data_home()
.ok_or("Could not determine data directory")?;
std::fs::create_dir_all(&config_dir)?;
std::fs::create_dir_all(&data_dir)?;
Ok(())
}
After:
use dir_spec::{config_home, data_home};
fn setup_config() -> Result<(), Box<dyn std::error::Error>> {
let config_dir = config_home()
.ok_or("Could not determine config directory")?;
let data_dir = data_home()
.ok_or("Could not determine data directory")?;
std::fs::create_dir_all(&config_dir)?;
std::fs::create_dir_all(&data_dir)?;
Ok(())
}
Example 2: Application Setup#
Before:
use dir_spec::Dir;
use std::path::PathBuf;
struct AppPaths {
config: PathBuf,
cache: PathBuf,
data: PathBuf,
}
impl AppPaths {
fn new(app_name: &str) -> Option<Self> {
Some(Self {
config: Dir::config_home()?.join(app_name),
cache: Dir::cache_home()?.join(app_name),
data: Dir::data_home()?.join(app_name),
})
}
}
After:
use dir_spec::{config_home, cache_home, data_home};
use std::path::PathBuf;
struct AppPaths {
config: PathBuf,
cache: PathBuf,
data: PathBuf,
}
impl AppPaths {
fn new(app_name: &str) -> Option<Self> {
Some(Self {
config: config_home()?.join(app_name),
cache: cache_home()?.join(app_name),
data: data_home()?.join(app_name),
})
}
}
Example 3: User Directories#
Before:
use dir_spec::Dir;
fn get_user_directories() {
if let Some(desktop) = Dir::desktop() {
println!("Desktop: {}", desktop.display());
}
if let Some(documents) = Dir::documents() {
println!("Documents: {}", documents.display());
}
if let Some(downloads) = Dir::downloads() {
println!("Downloads: {}", downloads.display());
}
}
After:
use dir_spec::{desktop, documents, downloads};
fn get_user_directories() {
if let Some(desktop) = desktop() {
println!("Desktop: {}", desktop.display());
}
if let Some(documents) = documents() {
println!("Documents: {}", documents.display());
}
if let Some(downloads) = downloads() {
println!("Downloads: {}", downloads.display());
}
}
Automated Migration#
You can use a simple find-and-replace to migrate most code:
Using sed (Unix/Linux/macOS)#
# Replace Dir::function_name() with function_name()
find . -name "*.rs" -exec sed -i '' 's/Dir::\([a-z_]*\)(/\1(/g' {} +
# Update imports
find . -name "*.rs" -exec sed -i '' 's/use dir_spec::Dir;/use dir_spec::*;/g' {} +
Using perl (cross-platform)#
# Replace Dir::function_name() with function_name()
find . -name "*.rs" -exec perl -pi -e 's/Dir::([a-z_]*)\(/$1(/g' {} +
# Update imports (you'll need to manually specify which functions to import)
find . -name "*.rs" -exec perl -pi -e 's/use dir_spec::Dir;/use dir_spec::*;/g' {} +
Manual Steps After Automated Migration#
-
Review imports: Replace
use dir_spec::*;with specific function imports for better code clarity:use dir_spec::{config_home, data_home, cache_home}; -
Update documentation: If you have documentation or examples that reference
Dir::, update them accordingly. -
Test thoroughly: Run your test suite to ensure everything works correctly.
Function Reference#
All functions remain unchanged except for how they're called:
| v0.4.0 | v0.5.0 |
|---|---|
Dir::bin_home() |
bin_home() |
Dir::cache_home() |
cache_home() |
Dir::config_home() |
config_home() |
Dir::config_local() |
config_local() |
Dir::data_home() |
data_home() |
Dir::data_local() |
data_local() |
Dir::desktop() |
desktop() |
Dir::documents() |
documents() |
Dir::downloads() |
downloads() |
Dir::fonts() |
fonts() |
Dir::home() |
home() |
Dir::music() |
music() |
Dir::pictures() |
pictures() |
Dir::preferences() |
preferences() |
Dir::publicshare() |
publicshare() |
Dir::runtime() |
runtime() |
Dir::state_home() |
state_home() |
Dir::templates() |
templates() |
Dir::videos() |
videos() |
Benefits of the New API#
- Simpler imports: Import only the functions you need
- Less redundant naming: No need to prefix with
Dir:: - More idiomatic Rust: Functions at module level are more common
- Better discoverability: IDE autocomplete shows all available functions directly
Need Help?#
If you encounter issues during migration, please:
- Check this migration guide again
- Review the updated documentation and examples
- File an issue on the GitHub repository with your specific use case