https://github.com/notpeter/env-home
There's no place like $HOME (rust crate)
https://github.com/notpeter/env-home
crate environment-variables home-directory rust
Last synced: 8 months ago
JSON representation
There's no place like $HOME (rust crate)
- Host: GitHub
- URL: https://github.com/notpeter/env-home
- Owner: notpeter
- License: apache-2.0
- Created: 2024-04-13T00:15:18.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-06-01T05:21:18.000Z (about 2 years ago)
- Last Synced: 2025-01-06T21:52:51.681Z (over 1 year ago)
- Topics: crate, environment-variables, home-directory, rust
- Language: Rust
- Homepage:
- Size: 43 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE-APACHE
Awesome Lists containing this project
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)](https://doc.rust-lang.org/std/env/fn.home_dir.html)
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](src/lib.rs) with no dependencies on other crates.
This functionality is comparable to Golang's [os.UserHomeDir()](https://pkg.go.dev/os#UserHomeDir)
or Python's [Path.home()](https://docs.python.org/3/library/pathlib.html#pathlib.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](https://crates.io/crates/dirs) crate.
## Usage
```shell
cargo add env_home
```
Crate exports a single function `env_home_dir` that returns `Option`
```rust
use env_home::env_home_dir as home_dir;
fn main() {
match home_dir() {
Some(path) => eprintln!("User home directory: {}", path.display()),
None => eprintln!("No home found. HOME/USERPROFILE not set or empty"),
}
}
```
See the [std::path::PathBuf documentation](https://doc.rust-lang.org/std/path/struct.PathBuf.html)
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`](https://doc.rust-lang.org/std/env/fn.home_dir.html)
was trying to be too smart. It calls Platform specific APIs like
([GetUserProfileDirectoryW](https://learn.microsoft.com/en-us/windows/win32/api/userenv/nf-userenv-getuserprofiledirectoryw)
on Windows or [getpwuid_r](https://linux.die.net/man/3/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`](https://doc.rust-lang.org/std/env/fn.home_dir.html)
provided by the standard library may be unexpected on Windows.
And thus was
[deprecated](https://doc.rust-lang.org/std/env/fn.home_dir.html#deprecation)
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](https://crates.io/crates/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](https://github.com/rust-lang/cargo/issues/12297)
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](https://doc.rust-lang.org/std/env/fn.set_var.html) 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](https://github.com/rust-lang/rust/issues/27970) and
[Setenv is not Thread Safe and C Doesn't Want to Fix It](https://www.evanjones.ca/setenv-is-not-thread-safe.html)
for more.
## License
Copyright (c) 2024 Peter Tripp
This project is licensed under the [MIT License](LICENSE-MIT)
or [Apache License, Version 2.0](LICENSE-APACHE) at your option.