git_iris/
context.rs

1use crate::token_optimizer::TokenOptimizer;
2use serde::Serialize;
3use std::fmt;
4
5#[derive(Serialize, Debug, Clone)]
6pub struct CommitContext {
7    pub branch: String,
8    pub recent_commits: Vec<RecentCommit>,
9    pub staged_files: Vec<StagedFile>,
10    pub project_metadata: ProjectMetadata,
11    pub user_name: String,
12    pub user_email: String,
13}
14
15#[derive(Serialize, Debug, Clone)]
16pub struct RecentCommit {
17    pub hash: String,
18    pub message: String,
19    pub author: String,
20    pub timestamp: String,
21}
22
23#[derive(Serialize, Debug, Clone)]
24pub struct StagedFile {
25    pub path: String,
26    pub change_type: ChangeType,
27    pub diff: String,
28    pub analysis: Vec<String>,
29    pub content: Option<String>,
30    pub content_excluded: bool,
31}
32
33#[derive(Serialize, Debug, Clone, PartialEq, Eq)]
34pub enum ChangeType {
35    Added,
36    Modified,
37    Deleted,
38}
39
40impl fmt::Display for ChangeType {
41    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42        match self {
43            Self::Added => write!(f, "Added"),
44            Self::Modified => write!(f, "Modified"),
45            Self::Deleted => write!(f, "Deleted"),
46        }
47    }
48}
49
50#[derive(Serialize, Debug, Clone, Default)]
51pub struct ProjectMetadata {
52    pub language: Option<String>,
53    pub framework: Option<String>,
54    pub dependencies: Vec<String>,
55    pub version: Option<String>,
56    pub build_system: Option<String>,
57    pub test_framework: Option<String>,
58    pub plugins: Vec<String>,
59}
60
61impl ProjectMetadata {
62    pub fn merge(&mut self, new: ProjectMetadata) {
63        if let Some(new_lang) = new.language {
64            match &mut self.language {
65                Some(lang) if !lang.contains(&new_lang) => {
66                    lang.push_str(", ");
67                    lang.push_str(&new_lang);
68                }
69                None => self.language = Some(new_lang),
70                _ => {}
71            }
72        }
73        self.dependencies.extend(new.dependencies.clone());
74        self.framework = self.framework.take().or(new.framework);
75        self.version = self.version.take().or(new.version);
76        self.build_system = self.build_system.take().or(new.build_system);
77        self.test_framework = self.test_framework.take().or(new.test_framework);
78        self.plugins.extend(new.plugins);
79        self.dependencies.sort();
80        self.dependencies.dedup();
81    }
82}
83
84impl CommitContext {
85    pub fn new(
86        branch: String,
87        recent_commits: Vec<RecentCommit>,
88        staged_files: Vec<StagedFile>,
89        project_metadata: ProjectMetadata,
90        user_name: String,
91        user_email: String,
92    ) -> Self {
93        Self {
94            branch,
95            recent_commits,
96            staged_files,
97            project_metadata,
98            user_name,
99            user_email,
100        }
101    }
102    pub fn optimize(&mut self, max_tokens: usize) {
103        let optimizer = TokenOptimizer::new(max_tokens);
104        optimizer.optimize_context(self);
105    }
106}