Crate unidirs

source ·
Expand description

Unified directories for different use cases of an application, providing standard directories for local development, when run as service or when run by a user.

This crate provides 4 main structures of interest:

  • LocalDirs to use a local directory as basis.
  • ServiceDirs for use when running as a service.
  • UserDirs for use when run by a local user directly.
  • UnifiedDirs as a combination of the above three to provide a common interface.

The simplest, but most opinionated, way of using this crate is the UnifiedDirs::simple function. It will use the local dirs unconditionally in debug mode and uses several heuristics to decide to use service or user dirs.

Passing the boolean flag can be done in any way possible. It is very common to pass it from command line arguments or use a environment variable to detect the service mode.

Using the simple builder

The call to UnifiedDirs::simple returns a SimpleBuilder that can be further configured to use all or only specific heuristics to detect a service or user mode.

use unidirs::{Directories, UnifiedDirs};

let dirs = UnifiedDirs::simple("com", "example", "app")
    .with_env()
    .with_args()
    .with_username()
    .build()
    .unwrap();

println!("cache dir: {}", dirs.cache_dir());
println!("config dir: {}", dirs.config_dir());
println!("data dir: {}", dirs.data_dir());

Using clap to pass a flag

This example uses the popular clap crate to parse and pass the service flag to UnifiedDirs.

use clap::Parser;
use unidirs::{Directories, UnifiedDirs};

#[derive(Parser)]
struct Args {
    #[arg(long, action, alias = "daemon")]
    service: bool,
}

let opt = Args::parse();
let dirs = UnifiedDirs::simple("com", "example", "app")
    .with(|_| opt.service)
    .build()
    .unwrap();

println!("cache dir: {}", dirs.cache_dir());
println!("config dir: {}", dirs.config_dir());
println!("data dir: {}", dirs.data_dir());

Using environment variables to detect service mode

In this sample we use the environment variable RUN_AS_SERVICE to detect the service mode. The variable can be anything, but pre-fixing it with the applications name is recommended to avoid name clashes (for example MYAPP_SERVICE).

use std::env;

use unidirs::{Directories, UnifiedDirs};

let service = env::var_os("RUN_AS_SERVICE").is_some();
let dirs = UnifiedDirs::simple("com", "example", "app")
    .with(|_| service)
    .build()
    .unwrap();

println!("cache dir: {}", dirs.cache_dir());
println!("config dir: {}", dirs.config_dir());
println!("data dir: {}", dirs.data_dir());

Re-exports

Structs

  • Local directories are meant mostly for debug purposes while developing an application. By default it provides all available directories under a .local folder in the current working directory.
  • Service directories are used for applications that run as a service (or often called daemon), usually run by a dedicated user account and controlled by the system rather than the user.
  • The simple builder is constructed through the UnifiedDirs::simple method and allows to further configure ways of detecting whether the application is run as a service or by the user.
  • User directories are used when applications are directly run by local regular users. The folder locations vary greatly by platform, as each has their own rules about where to put them.
  • A slice of a UTF-8 path (akin to str).
  • An owned, mutable UTF-8 path (akin to String).

Enums

  • Unified directories provide a common interface over all different ways of constructing directory providers. It provides constructors for each variant.

Traits

  • Common directories that are provided by all *Dirs structures. This can be used as an alternative to UnifiedDirs to abstract over the underlying provider implementation.