1#[derive(Debug, Clone)]
12pub struct LangConfig {
13 pub locale: String,
15 pub fallback_locale: String,
17 pub path: String,
19}
20
21impl LangConfig {
22 pub fn from_env() -> Self {
24 Self {
25 locale: std::env::var("APP_LOCALE").unwrap_or_else(|_| "en".to_string()),
26 fallback_locale: std::env::var("APP_FALLBACK_LOCALE")
27 .unwrap_or_else(|_| "en".to_string()),
28 path: std::env::var("LANG_PATH").unwrap_or_else(|_| "lang".to_string()),
29 }
30 }
31
32 pub fn builder() -> LangConfigBuilder {
34 LangConfigBuilder::default()
35 }
36}
37
38impl Default for LangConfig {
39 fn default() -> Self {
40 Self::from_env()
41 }
42}
43
44#[derive(Default)]
48pub struct LangConfigBuilder {
49 locale: Option<String>,
50 fallback_locale: Option<String>,
51 path: Option<String>,
52}
53
54impl LangConfigBuilder {
55 pub fn locale(mut self, locale: impl Into<String>) -> Self {
57 self.locale = Some(locale.into());
58 self
59 }
60
61 pub fn fallback_locale(mut self, fallback: impl Into<String>) -> Self {
63 self.fallback_locale = Some(fallback.into());
64 self
65 }
66
67 pub fn path(mut self, path: impl Into<String>) -> Self {
69 self.path = Some(path.into());
70 self
71 }
72
73 pub fn build(self) -> LangConfig {
75 let default = LangConfig::from_env();
76 LangConfig {
77 locale: self.locale.unwrap_or(default.locale),
78 fallback_locale: self.fallback_locale.unwrap_or(default.fallback_locale),
79 path: self.path.unwrap_or(default.path),
80 }
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
91 fn from_env_and_defaults() {
92 std::env::remove_var("APP_LOCALE");
94 std::env::remove_var("APP_FALLBACK_LOCALE");
95 std::env::remove_var("LANG_PATH");
96
97 let config = LangConfig::from_env();
98 assert_eq!(config.locale, "en");
99 assert_eq!(config.fallback_locale, "en");
100 assert_eq!(config.path, "lang");
101
102 std::env::set_var("APP_LOCALE", "es");
104 std::env::set_var("APP_FALLBACK_LOCALE", "fr");
105 std::env::set_var("LANG_PATH", "resources/lang");
106
107 let config = LangConfig::from_env();
108 assert_eq!(config.locale, "es");
109 assert_eq!(config.fallback_locale, "fr");
110 assert_eq!(config.path, "resources/lang");
111
112 let config = LangConfig::default();
114 assert_eq!(config.locale, "es");
115
116 std::env::remove_var("APP_LOCALE");
118 std::env::remove_var("APP_FALLBACK_LOCALE");
119 std::env::remove_var("LANG_PATH");
120 }
121
122 #[test]
123 fn builder_overrides_fields() {
124 let config = LangConfig::builder()
125 .locale("pt-br")
126 .fallback_locale("en")
127 .path("translations")
128 .build();
129
130 assert_eq!(config.locale, "pt-br");
131 assert_eq!(config.fallback_locale, "en");
132 assert_eq!(config.path, "translations");
133 }
134
135 #[test]
136 fn builder_fills_unset_from_defaults() {
137 let config = LangConfig::builder().locale("de").build();
138
139 assert_eq!(config.locale, "de");
140 }
144}