# cfgmatic-paths

[![Crates.io](https://img.shields.io/crates/v/cfgmatic-paths)](https://crates.io/crates/cfgmatic-paths)
[![Docs.rs](https://docs.rs/cfgmatic-paths/badge.svg)](https://docs.rs/cfgmatic-paths)
[![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue)](LICENSE-MIT)
[![Unsafe](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/)

Cross-platform configuration path discovery following XDG and platform conventions.

## Overview

This crate provides a platform-agnostic way to discover configuration directories following the conventions of each operating system:

- **Unix/Linux**: XDG Base Directory Specification
- **macOS CLI**: XDG (same as Unix)
- **macOS GUI**: Application Support directories (with `macos-gui` feature)
- **Windows**: Known Folder IDs (AppData, ProgramData)

## Architecture

```
crates/cfgmatic-paths/
├── Cargo.toml
├── src/
│   ├── lib.rs           # Public API and convenience functions
│   ├── builder.rs       # PathsBuilder and PathFinder
│   ├── core/            # Core domain types
│   │   ├── app_type.rs  # AppType (CLI, GUI, Service)
│   │   ├── config_tier.rs # ConfigTier (User, Local, System)
│   │   └── pattern.rs   # FilePattern for matching config files
│   ├── platform/        # Platform-specific implementations
│   │   ├── mod.rs       # DirectoryFinder trait
│   │   ├── unix.rs      # XDG for Unix/Linux/macOS CLI
│   │   ├── windows.rs   # Windows Known Folders
│   │   └── macos_gui.rs # macOS Application Support
│   ├── env/             # Environment abstraction for testing
│   │   ├── mod.rs       # Env trait
│   │   └── std_env.rs   # StdEnv implementation
│   └── filesystem/      # Filesystem abstraction for testing
│       ├── mod.rs       # Fs trait
│       └── std_fs.rs    # StdFs implementation
```

## Usage

### Basic Usage

```rust
use cfgmatic_paths::PathsBuilder;

// Create a path finder for your application
let finder = PathsBuilder::new("myapp").build();

// Get user config directories
let user_dirs = finder.user_dirs();
println!("User config dirs: {:?}", user_dirs);

// Ensure the primary user config directory exists
if let Ok(config_dir) = finder.ensure_user_config_dir() {
    println!("Config dir: {}", config_dir.display());
}
```

### Convenience Functions

```rust
use cfgmatic_paths::{find_existing_dir, ensure_config_dir, get_all_dirs};

// Find the first existing config directory
if let Some(dir) = find_existing_dir("myapp") {
    println!("Found: {}", dir.display());
}

// Ensure user config directory exists
let config_dir = ensure_config_dir("myapp")?;

// Get all directories with metadata
for info in get_all_dirs("myapp") {
    println!("{:?}: {} (exists: {})",
        info.tier, info.path.display(), info.exists);
}
```

## Configuration Tiers

Configuration directories are organized into three tiers:

1. **User** (`ConfigTier::User`): User-specific configs in home directory.
   Highest priority, typically writable.

2. **Local** (`ConfigTier::Local`): Machine-specific configs.
   Medium priority, may be writable.

3. **System** (`ConfigTier::System`): System-wide configs.
   Lowest priority, typically read-only.

## Platform Details

### Unix/Linux (XDG)

- User: `$XDG_CONFIG_HOME/<app>/` (default: `~/.config/<app>/`)
- Legacy: `~/.<app>rc` (optional, enabled by default)
- System: `$XDG_CONFIG_DIRS/<app>/` (default: `/etc/xdg/<app>/`)

### macOS

#### CLI Applications (default)
Uses XDG (same as Unix/Linux).

#### GUI Applications (with `macos-gui` feature)
- User: `~/Library/Application Support/<bundle-id>/`
- System: `/Library/Application Support/<bundle-id>/`

### Windows

- User Roaming: `%APPDATA%\<Company>\<App>\`
- User Local: `%LOCALAPPDATA%\<Company>\<App>\`
- System: `%PROGRAMDATA%\<Company>\<App>\`

## Testing

The crate provides abstractions for testing:

- `Env`: Mock environment variables
- `Fs`: Mock filesystem operations

These allow testing without modifying the actual environment or filesystem.

## Features

- `default`: No additional features enabled.
- `macos-gui`: Use macOS Application Support directories instead of XDG.
- `test-helpers`: Additional utilities for testing (future).

## Relationship to cfgmatic

This crate is the foundation for the `cfgmatic` configuration framework:

- `cfgmatic-paths`: Path discovery (this crate)
- `cfgmatic`: File search, merging, watching (uses `cfgmatic-paths`)

The separation allows:
1. Independent use of path discovery
2. Testing without filesystem dependencies
3. Platform-specific optimizations

## License

This project is licensed under either of

- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)

at your option.
