env_home

Crates.ioenv_home
lib.rsenv_home
version0.1.0
sourcesrc
created_at2024-04-22 21:56:52.603594
updated_at2024-04-22 21:56:52.603594
descriptionGet the user home directory in a cross-platform way.
homepagehttps://github.com/notpeter/env-home
repositoryhttps://github.com/notpeter/env-home
max_upload_size
id1216984
size25,254
Peter Tripp (notpeter)

documentation

README

env_home rust crate

A pure-Rust crate for determining user home directories via environment variables in a platform independent manner with no external dependencies.

Check HOME on Unix and USERPROFILE on Windows.

Description

env_home is a general purpose crate for determining the current user home directory via environment variables.

It can be used as drop-in replacement for std::env::home_dir (deprecated) from the rust standard library.

Unlike std::env::home_dir this crate only looks at environment variables and does attempt to fallback on platform specific APIs. As a result implementation of env_home_dir is very simple with no dependencies on other crates.

This functionality is comparable to Golang's os.UserHomeDir() or Python's Path.home().

env_home::env_home_dir Behavior

The API of this crate is a single function env_home_dir which attempts to fetch a user's home directory from environment variables in a platform independent way supporting Windows and Unix (Linux/MacOS/BSD/WSL, etc).

Platform Environment Variable Example
MacOS, Linux or other Unix HOME /home/user
Windows Subsystem for Linux (WSL) HOME /home/user
Windows Native USERPROFILE C:\\Users\\user
Others (WASM, etc) N/A None
  1. If the environment variable is unset, None is returned.
  2. If the environment variable is set to an empty string, None is returned.
  3. On non-unix / non-windows platforms (like WASM) that don't implement a home directory None will be returned.
  4. If the environment variable is set to a non-empty string, the value is returned as a PathBuf.

That's it.

If you need a more full-service crate consider using the dirs crate.

Usage

cargo add env_home

Crate exports a single function env_home_dir that returns Option<PathBuf>

use env_home::env_home_dir as home_dir;
fn main() {
    match home_dir() {
        Some(path) => println!("User home directory: {}", path.display()),
        None => println!("No home found. HOME/USERPROFILE not set or empty"),
    }
}

See the std::path::PathBuf documentation for more information on how to use PathBuf objects.

Differences with std::env::home_dir

env_home_dir returns None instead of "" when HOME or USERPROFILE is set to an empty string.

I believe std::env::home_dir was trying to be too smart. It calls Platform specific APIs like (GetUserProfileDirectoryW on Windows or getpwuid_r on Unix as a fallback when HOME or USERPROFILE environment variables are not set. We just give up and return None.

This crate exists because the behavior of home_dir provided by the standard library may be unexpected on Windows. And thus was deprecated and has remained broken / unfixed since Rust 1.29.0 (Sept 2018).

As an alternative to the home crate

Although many projects have switched from std::env::home_dir to home::home_dir provided by the home crate because it was maintained by the cargo team and thus presumably more "official". The Cargo team has clarified that the home crate is not intended for general use:

"the cargo team doesn't want to take on the maintenance of home as a general-purpose crate for the community" [...] "we are thinking of documenting that home is not intended for anything but use inside of cargo and rustup, and suggest people use some other crate instead." source

As a result the home crate refuses to compile for WASM target and they have have no plans to fix this.

env_home crate implements a fallback no-op which returns None on non-windows / non-unix platforms like WASM.

Other Notes

Using std::env::set_var to alter your environment at runtime is unsafe in multi-threaded applications. Full stop. It may result in random panics or undefined behavior. You have have been warned.

Bonus: cargo runs tests in parallel threads by-default, so even if you app is not multi-threaded if you have tests that invoke std::env::set_var be sure to set RUST_TEST_THREADS=1 or use cargo test -- --test-threads=1 or your tests may intermittently panic and fail.

See rust-lang/rust#27970 and Setenv is not Thread Safe and C Doesn't Want to Fix It for more.

License

Copyright (c) 2024 Peter Tripp

This project is licensed under the MIT License or Apache License, Version 2.0 at your option.

Commit count: 14

cargo fmt