1use crate::color::resolve_color;
2use std::env;
3
4#[derive(Debug, Clone)]
6pub struct Config {
7 pub shell: String,
8 pub shell_flags: Vec<String>,
9 pub comment_color: Option<String>,
10}
11
12impl Default for Config {
13 fn default() -> Self {
14 Self {
15 shell: "bash".to_string(),
16 shell_flags: vec![],
17 comment_color: None,
18 }
19 }
20}
21
22impl Config {
23 pub fn from_env() -> Self {
25 let mut config = Config::default();
26
27 if let Ok(shell) = env::var("ECHO_COMMENT_SHELL") {
29 config.shell = shell;
30 }
31
32 if let Ok(flags) = env::var("ECHO_COMMENT_SHELL_FLAGS") {
33 config.shell_flags = flags.split_whitespace().map(|s| s.to_string()).collect();
34 }
35
36 if let Ok(color) = env::var("ECHO_COMMENT_COLOR") {
38 config.comment_color = Some(resolve_color(&color));
39 }
40
41 config
42 }
43
44 pub fn shebang(&self) -> String {
46 if self.shell_flags.is_empty() {
47 format!("#!/usr/bin/env {}", self.shell)
48 } else {
49 format!(
50 "#!/usr/bin/env -S {} {}",
51 self.shell,
52 self.shell_flags.join(" ")
53 )
54 }
55 }
56
57 pub fn colorize(&self, text: &str) -> String {
59 if let Some(color) = &self.comment_color {
60 format!("{}{}\x1b[0m", color, text)
61 } else {
62 text.to_string()
63 }
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn test_default_config() {
73 let config = Config::default();
74 assert_eq!(config.shell, "bash");
75 assert!(config.shell_flags.is_empty());
76 assert!(config.comment_color.is_none());
77 }
78
79 #[test]
80 fn test_shebang_generation() {
81 let config = Config::default();
82 assert_eq!(config.shebang(), "#!/usr/bin/env bash");
83
84 let config = Config {
85 shell: "zsh".to_string(),
86 shell_flags: vec!["-euo".to_string(), "pipefail".to_string()],
87 comment_color: None,
88 };
89 assert_eq!(config.shebang(), "#!/usr/bin/env -S zsh -euo pipefail");
90 }
91
92 #[test]
93 fn test_colorize() {
94 let config = Config::default();
95 assert_eq!(config.colorize("test"), "test");
96
97 let config = Config {
98 shell: "bash".to_string(),
99 shell_flags: vec![],
100 comment_color: Some("\x1b[0;32m".to_string()),
101 };
102 assert_eq!(config.colorize("test"), "\x1b[0;32mtest\x1b[0m");
103 }
104
105 #[test]
106 fn test_config_construction() {
107 let config = Config {
109 shell: "zsh".to_string(),
110 shell_flags: vec!["-euo".to_string(), "pipefail".to_string()],
111 comment_color: Some("red".to_string()),
112 };
113
114 assert_eq!(config.shell, "zsh");
115 assert_eq!(config.shell_flags, vec!["-euo", "pipefail"]);
116 assert_eq!(config.comment_color, Some("red".to_string()));
117 }
118}