logtail_rust/struct/
env_config.rs1use serde::Serialize;
2use std::env;
3use std::str::FromStr;
4use strum_macros::{Display, EnumString};
5
6#[derive(Debug, EnumString, Display, PartialEq, Serialize, Clone)]
7pub enum EnvEnum {
8 #[strum(serialize = "local")]
9 Local,
10 #[strum(serialize = "qa")]
11 QA,
12 #[strum(serialize = "preprod")]
13 PreProd,
14 #[strum(serialize = "prod")]
15 Prod,
16}
17
18pub struct EnvConfig {
19 pub app_version: String,
20 pub environment: EnvEnum,
21 pub logs_source_token: String,
22 pub verbose: bool,
23}
24
25impl Default for EnvConfig {
26 fn default() -> Self {
29 Self::new(env!("CARGO_PKG_VERSION").to_string(), true)
30 }
31}
32impl EnvConfig {
33 pub fn from_values(
34 app_version: String,
35 environment: EnvEnum,
36 logs_source_token: String,
37 verbose: bool,
38 ) -> Self {
39 EnvConfig {
40 app_version,
41 environment,
42 logs_source_token,
43 verbose,
44 }
45 }
46
47 pub fn new(app_version: String, verbose: bool) -> Self {
48 dotenv::dotenv().ok();
49 let environment_string = env::var("ENVIRONMENT").expect("missing variable: ENVIRONMENT");
50 let environment = EnvEnum::from_str(&environment_string).unwrap();
51 let logs_source_token =
52 env::var("LOGS_SOURCE_TOKEN").expect("missing variable: LOGS_SOURCE_TOKEN");
53
54 EnvConfig {
55 app_version,
56 environment,
57 logs_source_token,
58 verbose,
59 }
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66 use serial_test::serial;
67
68 #[test]
71 fn display_all_variants() {
72 assert_eq!(EnvEnum::Local.to_string(), "local");
73 assert_eq!(EnvEnum::QA.to_string(), "qa");
74 assert_eq!(EnvEnum::PreProd.to_string(), "preprod");
75 assert_eq!(EnvEnum::Prod.to_string(), "prod");
76 }
77
78 #[test]
79 fn parse_valid_variants() {
80 assert_eq!(EnvEnum::from_str("local").unwrap(), EnvEnum::Local);
81 assert_eq!(EnvEnum::from_str("qa").unwrap(), EnvEnum::QA);
82 assert_eq!(EnvEnum::from_str("preprod").unwrap(), EnvEnum::PreProd);
83 assert_eq!(EnvEnum::from_str("prod").unwrap(), EnvEnum::Prod);
84 }
85
86 #[test]
87 fn parse_invalid_returns_err() {
88 assert!(EnvEnum::from_str("staging").is_err());
89 assert!(EnvEnum::from_str("LOCAL").is_err());
90 assert!(EnvEnum::from_str("").is_err());
91 }
92
93 #[test]
94 fn equality() {
95 assert_eq!(EnvEnum::Local, EnvEnum::Local);
96 assert_eq!(EnvEnum::Prod, EnvEnum::Prod);
97 assert_ne!(EnvEnum::Local, EnvEnum::Prod);
98 assert_ne!(EnvEnum::QA, EnvEnum::PreProd);
99 }
100
101 #[test]
102 fn serde_serialize() {
103 assert_eq!(serde_json::to_string(&EnvEnum::Local).unwrap(), "\"Local\"");
104 assert_eq!(serde_json::to_string(&EnvEnum::QA).unwrap(), "\"QA\"");
105 assert_eq!(
106 serde_json::to_string(&EnvEnum::PreProd).unwrap(),
107 "\"PreProd\""
108 );
109 assert_eq!(serde_json::to_string(&EnvEnum::Prod).unwrap(), "\"Prod\"");
110 }
111
112 #[test]
115 fn from_values_sets_all_fields() {
116 let config = EnvConfig::from_values(
117 "1.2.3".to_string(),
118 EnvEnum::Prod,
119 "my-token".to_string(),
120 false,
121 );
122
123 assert_eq!(config.app_version, "1.2.3");
124 assert_eq!(config.environment, EnvEnum::Prod);
125 assert_eq!(config.logs_source_token, "my-token");
126 assert!(!config.verbose);
127 }
128
129 #[test]
132 #[serial]
133 fn new_reads_env_vars() {
134 env::set_var("ENVIRONMENT", "qa");
135 env::set_var("LOGS_SOURCE_TOKEN", "test-token-123");
136
137 let config = EnvConfig::new("0.5.0".to_string(), true);
138
139 assert_eq!(config.app_version, "0.5.0");
140 assert_eq!(config.environment, EnvEnum::QA);
141 assert_eq!(config.logs_source_token, "test-token-123");
142 assert!(config.verbose);
143 }
144
145 #[test]
146 #[serial]
147 fn default_uses_cargo_version() {
148 env::set_var("ENVIRONMENT", "local");
149 env::set_var("LOGS_SOURCE_TOKEN", "token");
150
151 let config = EnvConfig::default();
152
153 assert_eq!(config.app_version, env!("CARGO_PKG_VERSION"));
154 assert!(config.verbose);
155 }
156
157 #[test]
158 #[serial]
159 #[should_panic(expected = "missing variable: ENVIRONMENT")]
160 fn new_panics_missing_environment() {
161 env::remove_var("ENVIRONMENT");
162 env::set_var("LOGS_SOURCE_TOKEN", "token");
163
164 EnvConfig::new("1.0.0".to_string(), false);
165 }
166
167 #[test]
168 #[serial]
169 #[should_panic]
170 fn new_panics_invalid_environment() {
171 env::set_var("ENVIRONMENT", "staging");
172 env::set_var("LOGS_SOURCE_TOKEN", "token");
173
174 EnvConfig::new("1.0.0".to_string(), false);
175 }
176
177 #[test]
178 #[serial]
179 #[should_panic(expected = "missing variable: LOGS_SOURCE_TOKEN")]
180 fn new_panics_missing_token() {
181 env::set_var("ENVIRONMENT", "local");
182 env::remove_var("LOGS_SOURCE_TOKEN");
183
184 EnvConfig::new("1.0.0".to_string(), false);
185 }
186}