git_iris/
common.rs

1use crate::config::Config;
2use crate::instruction_presets::get_instruction_preset_library;
3use crate::llm_providers::LLMProviderType;
4use anyhow::Result;
5use clap::Args;
6use std::str::FromStr;
7
8#[derive(Clone, Copy, PartialEq, Eq, Debug)]
9pub enum DetailLevel {
10    Minimal,
11    Standard,
12    Detailed,
13}
14
15impl FromStr for DetailLevel {
16    type Err = anyhow::Error;
17
18    fn from_str(s: &str) -> Result<Self, Self::Err> {
19        match s.to_lowercase().as_str() {
20            "minimal" => Ok(Self::Minimal),
21            "standard" => Ok(Self::Standard),
22            "detailed" => Ok(Self::Detailed),
23            _ => Err(anyhow::anyhow!("Invalid detail level: {}", s)),
24        }
25    }
26}
27
28impl DetailLevel {
29    pub fn as_str(&self) -> &'static str {
30        match self {
31            Self::Minimal => "minimal",
32            Self::Standard => "standard",
33            Self::Detailed => "detailed",
34        }
35    }
36}
37
38#[derive(Args, Clone, Default, Debug)]
39pub struct CommonParams {
40    /// Override default LLM provider
41    #[arg(long, help = "Override default LLM provider", value_parser = available_providers_parser)]
42    pub provider: Option<String>,
43
44    /// Custom instructions for this operation
45    #[arg(short, long, help = "Custom instructions for this operation")]
46    pub instructions: Option<String>,
47
48    /// Select an instruction preset
49    #[arg(long, help = "Select an instruction preset")]
50    pub preset: Option<String>,
51
52    /// Enable or disable Gitmoji
53    #[arg(long, help = "Enable or disable Gitmoji")]
54    pub gitmoji: Option<bool>,
55
56    /// Set the detail level
57    #[arg(
58        long,
59        help = "Set the detail level (minimal, standard, detailed)",
60        default_value = "standard"
61    )]
62    pub detail_level: String,
63}
64
65impl CommonParams {
66    pub fn apply_to_config(&self, config: &mut Config) -> Result<()> {
67        if let Some(provider) = &self.provider {
68            config.default_provider = LLMProviderType::from_str(provider)?.to_string();
69        }
70        if let Some(instructions) = &self.instructions {
71            config.set_temp_instructions(Some(instructions.clone()));
72        }
73        if let Some(preset) = &self.preset {
74            config.set_temp_preset(Some(preset.clone()));
75        }
76        if let Some(use_gitmoji) = self.gitmoji {
77            config.use_gitmoji = use_gitmoji;
78        }
79        Ok(())
80    }
81}
82
83/// Validate provider input against available providers
84pub fn available_providers_parser(s: &str) -> Result<String, String> {
85    let available_providers = crate::llm::get_available_provider_names();
86    if available_providers.contains(&s.to_lowercase()) && s.to_lowercase() != "test" {
87        Ok(s.to_lowercase())
88    } else {
89        Err(format!(
90            "Invalid provider. Available providers are: {}",
91            available_providers.join(", ")
92        ))
93    }
94}
95
96pub fn get_combined_instructions(config: &Config) -> String {
97    let mut prompt = String::from("\n\n");
98
99    let preset_library = get_instruction_preset_library();
100    if let Some(preset_instructions) = preset_library.get_preset(config.instruction_preset.as_str())
101    {
102        prompt.push_str(&format!(
103            "\n\nUse this style for the commit message:\n{}\n\n",
104            preset_instructions.instructions
105        ));
106    }
107
108    if !config.instructions.is_empty() {
109        prompt.push_str(&format!(
110            "\n\nAdditional instructions for the commit message:\n{}\n\n",
111            config.instructions
112        ));
113    }
114
115    prompt
116}