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}