nested_env_parser/lib.rs
1//! Nested Env Parser is a crate for getting the final value of a string with nested environment variables.
2//!
3//! # installation
4//!
5//! Install using cargo:
6//!
7//! ```no_run,ignore
8//! cargo install nested-env-parser
9//! ```
10//!
11//! # Usage
12//!
13//! ## On Unix
14//!
15//! ```
16//! use clap::Parser;
17//! use nested_env_parser::Env;
18//!
19//! #[derive(Clone, Debug, Parser)]
20//! struct Opts {
21//! #[clap(env)]
22//! value_with_env: Env,
23//! }
24//!
25//! fn main() {
26//! std::env::set_var("VALUE1", "Hello,");
27//! std::env::set_var("VALUE2", "world");
28//! std::env::set_var("VALUE_WITH_ENV", "$VALUE1 ${VALUE2}!");
29//!
30//! let opts = Opts::parse();
31//!
32//! assert_eq!("Hello, world!", &opts.value_with_env);
33//! }
34//! ```
35//! ## On Windows
36//!
37//! ```no_run
38//! use clap::Parser;
39//! use nested_env_parser::Env;
40//!
41//! #[derive(Clone, Debug, Parser)]
42//! struct Opts {
43//! #[clap(env)]
44//! value_with_env: Env,
45//! }
46//!
47//! fn main() {
48//! std::env::set_var("VALUE1", "Hello");
49//! std::env::set_var("VALUE2", "world");
50//! std::env::set_var("VALUE_WITH_ENV", "%VALUE1%, %VALUE2%!");
51//!
52//! let opts = Opts::parse();
53//!
54//! assert_eq!("Hello, world!", &opts.value_with_env);
55//! }
56//! ```
57#![warn(missing_docs)]
58
59use std::ops::Deref;
60use envmnt::{ExpandOptions, ExpansionType};
61
62/// String with nested environment variables
63#[derive(Clone, Debug, PartialEq, Eq)]
64pub struct Env(String);
65
66impl Env {
67
68 /// Create new Env
69 pub fn new(value: &str) -> Self {
70 value.into()
71 }
72}
73
74
75impl From<&str> for Env {
76 fn from(value: &str) -> Self {
77 let mut options = ExpandOptions::new();
78
79 options.expansion_type = match std::env::consts::FAMILY {
80 "unix" => Some(ExpansionType::Unix),
81 "windows" => Some(ExpansionType::Windows),
82 _ => Some(ExpansionType::All)
83 };
84 let result = envmnt::expand(value, Some(options));
85 Env(result)
86 }
87}
88
89impl Deref for Env {
90 type Target = String;
91
92 fn deref(&self) -> &Self::Target {
93 &self.0
94 }
95}
96
97impl<T> AsRef<T> for Env
98where
99 T: ?Sized,
100 <Env as Deref>::Target: AsRef<T>,
101{
102 fn as_ref(&self) -> &T {
103 self.deref().as_ref()
104 }
105}
106
107impl PartialEq<String> for Env {
108 fn eq(&self, other: &String) -> bool {
109 *self.deref() == *other
110 }
111}
112impl PartialEq<Env> for String {
113 fn eq(&self, other: &Env) -> bool {
114 *self == *other.deref()
115 }
116}
117
118impl PartialEq<str> for Env {
119 fn eq(&self, other: &str) -> bool {
120 *self.deref() == *other
121 }
122}
123impl PartialEq<Env> for str {
124 fn eq(&self, other: &Env) -> bool {
125 *self == *other.deref()
126 }
127}