Macro try_app_path

Source
macro_rules! try_app_path {
    () => { ... };
    ($path:expr) => { ... };
    ($path:expr, env = $env_var:expr) => { ... };
    ($path:expr, override = $override_expr:expr) => { ... };
    ($path:expr, fn = $override_fn:expr) => { ... };
}
Expand description

Fallible version of app_path! that returns a Result instead of panicking.

This macro provides the same convenient syntax as app_path! but returns Result<AppPath, AppPathError> for explicit error handling. Perfect for libraries and applications that need graceful error handling.

§Syntax

  • try_app_path!() - Application base directory (equivalent to AppPath::try_new())
  • try_app_path!(path) - Simple path creation (equivalent to AppPath::try_with(path))
  • try_app_path!(path, env = "VAR_NAME") - With environment variable override
  • try_app_path!(path, override = expression) - With any optional override expression
  • try_app_path!(path, fn = function) - With function-based override logic

§Examples

§Basic Usage

use app_path::try_app_path;

let config = try_app_path!("config.toml")?;
let database = try_app_path!("data/users.db")?;

§Environment Variable Overrides

use app_path::try_app_path;

let log_file = try_app_path!("logs/app.log", env = "LOG_PATH")?;
log_file.create_parents()?;

§Custom Override Logic

use app_path::try_app_path;

let custom_path = std::env::var("DATA_HOME").ok();
let data_dir = try_app_path!("data", override = custom_path)?;

§Function-Based Override

use app_path::try_app_path;

let cache_dir = try_app_path!("cache", fn = || std::env::var("CACHE_DIR").ok())?;

§Error Handling

use app_path::{try_app_path, AppPathError};

match try_app_path!("config.toml") {
    Ok(config) => println!("Config: {}", config.display()),
    Err(AppPathError::ExecutableNotFound(msg)) => {
        eprintln!("Cannot find executable: {msg}");
    }
    Err(AppPathError::InvalidExecutablePath(msg)) => {
        eprintln!("Invalid executable path: {msg}");
    }
    Err(AppPathError::IoError(io_err)) => {
        eprintln!("I/O operation failed: {io_err}");
        // Access original error details for specific handling
        match io_err.kind() {
            std::io::ErrorKind::PermissionDenied => {
                eprintln!("Permission denied - check file permissions");
            }
            _ => eprintln!("Other I/O error"),
        }
    }
}

§Library Usage

use app_path::try_app_path;

pub fn load_config() -> Result<String, Box<dyn std::error::Error>> {
    let config_path = try_app_path!("config.toml")?;
    std::fs::read_to_string(&config_path).map_err(Into::into)
}

§Comparison with app_path!

Featureapp_path!try_app_path!
Return typeAppPathResult<AppPath, AppPathError>
Error handlingPanics on failureReturns Err on failure
Use caseApplicationsLibraries, explicit error handling
SyntaxSameSame
PerformanceSameSame

§When to Use

  • Use try_app_path! for libraries, when you need graceful error handling, or when integrating with other fallible operations
  • Use app_path! for applications where you want to fail fast on system errors

§See Also