echo_comment/
config.rs

1use crate::color::resolve_color;
2use std::env;
3
4/// Configuration for echo-comment behavior
5#[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    /// Create configuration from environment variables
24    pub fn from_env() -> Self {
25        let mut config = Config::default();
26
27        // Shell configuration
28        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        // Color configuration
37        if let Ok(color) = env::var("ECHO_COMMENT_COLOR") {
38            config.comment_color = Some(resolve_color(&color));
39        }
40
41        config
42    }
43
44    /// Generate the shebang line based on shell and flags
45    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    /// Wrap text with color codes if color is configured
58    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        // Test that we can construct configs directly for testing
108        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}