kaizen/interchange/
diff_attribution.rs1use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
7pub struct DiffAttributionOptions {
8 pub include_raw_patch: bool,
9}
10
11#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
12pub struct DiffAttribution {
13 pub session_id: String,
14 pub commit: String,
15 pub summary: DiffSummary,
16 #[serde(default, skip_serializing_if = "Vec::is_empty")]
17 pub files: Vec<FileDiffAttribution>,
18 #[serde(default, skip_serializing_if = "Option::is_none")]
19 pub raw_patch: Option<String>,
20}
21
22#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
23pub struct DiffSummary {
24 pub files_changed: u32,
25 pub additions: u32,
26 pub deletions: u32,
27}
28
29#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
30pub struct FileDiffAttribution {
31 pub path: String,
32 pub change: DiffChangeKind,
33 pub additions: u32,
34 pub deletions: u32,
35 #[serde(default, skip_serializing_if = "Vec::is_empty")]
36 pub hunks: Vec<DiffHunkAttribution>,
37 #[serde(default, skip_serializing_if = "Option::is_none")]
38 pub raw_patch: Option<String>,
39}
40
41#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
42#[serde(rename_all = "snake_case")]
43pub enum DiffChangeKind {
44 Added,
45 Modified,
46 Deleted,
47 Renamed { previous_path: String },
48}
49
50#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
51pub struct DiffHunkAttribution {
52 pub old_start: u32,
53 pub new_start: u32,
54 pub old_lines: u32,
55 pub new_lines: u32,
56 #[serde(default, skip_serializing_if = "Option::is_none")]
57 pub prompt_fingerprint: Option<String>,
58 #[serde(default, skip_serializing_if = "Option::is_none")]
59 pub raw_patch: Option<String>,
60}
61
62impl DiffAttributionOptions {
63 pub fn include_raw_patch() -> Self {
64 Self {
65 include_raw_patch: true,
66 }
67 }
68}
69
70impl DiffAttribution {
71 pub fn new(session_id: impl Into<String>, commit: impl Into<String>) -> Self {
72 Self {
73 session_id: session_id.into(),
74 commit: commit.into(),
75 summary: DiffSummary::default(),
76 files: Vec::new(),
77 raw_patch: None,
78 }
79 }
80
81 pub fn with_raw_patch(
82 mut self,
83 raw_patch: impl Into<String>,
84 options: DiffAttributionOptions,
85 ) -> Self {
86 if options.include_raw_patch {
87 self.raw_patch = Some(raw_patch.into());
88 }
89 self
90 }
91}