1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
//! Zenv is a dotenv loader which parses and loads your environment variables from a `.env` file. //! //! This crate also supports variable substitution inside your .env file, if not found then //! tries to fetch from the running operating system. By default, this is disabled. //! //! _This crate only meant to use inside a development environment._ //! //! Example //! ``` //! use zenv::{zenv, Zenv}; //! //! fn main() { //! Zenv::new(".env", false).configure().ok(); //! // is equivalent to //! zenv!(); //! //! // with other file //! zenv!(".env.development"); //! //! // or with variable substitution //! zenv!(".env.development", true); //! } //! ``` mod parser; use std::{ collections::HashMap, fs::read_to_string, io::{Error, ErrorKind, Result}, path::PathBuf, }; // Just re-exporting to use as a standalone parser pub use parser::{KeyVal, Line, Lines, Quote}; /// Use this to load and configure the environment variables #[derive(Debug)] pub struct Zenv { path: PathBuf, expand: bool, } impl Zenv { /// Create a new instance of Zenv with the provided file path pub fn new(path: &str, expand: bool) -> Self { Self { path: PathBuf::from(path), expand, } } /// Read and parse the file from provided path and returns a hashmap /// /// Example /// ``` /// let parsed = zenv::Zenv::new("tests/.env.basic", false).parse().unwrap(); /// /// assert_eq!(parsed.get("BASIC"), Some(&"basic".to_string())) /// ``` pub fn parse(&self) -> Result<HashMap<String, String>> { let path = &self.path; if !path.exists() { return Err(Error::new( ErrorKind::NotFound, format!("Unable to find file - {}", path.display()), )); } let lines = { let r = read_to_string(path)?; Lines::from(r.as_str()) }; let hash = match self.expand { true => lines.expand(), false => lines.to_hash_map(), }; Ok(hash) } /// Parse the file using [Zenv::parse] and sets the environment variable /// /// Example /// ``` /// zenv::Zenv::new("tests/.env.basic", false).configure().ok(); /// /// assert_eq!(std::env::var_os("BASIC"), Some("basic".into())) /// ``` pub fn configure(&self) -> Result<()> { let vars = self.parse()?; for (key, val) in vars { std::env::set_var(key, val); } Ok(()) } } /// This macro can be used as a shortcut for [`Zenv`] /// /// Example /// ``` /// use zenv::zenv; /// /// zenv!(); /// /// // with other file /// zenv!(".env.development"); /// /// // or with variable substitution /// zenv!(".env.development", true); /// ```` #[macro_export] macro_rules! zenv { () => { zenv::Zenv::new(".env", false).configure().ok() }; ($path:expr) => { zenv::Zenv::new($path, false).configure().ok() }; ($path:expr, $expand:expr) => { zenv::Zenv::new($path, $expand).configure().ok() }; }