1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4pub const SCHEMA_BUILDFIX_PLAN_V1: &str = "buildfix.plan.v1";
6
7#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
8pub struct BuildfixPlanV1 {
9 pub schema: String,
10 pub source: BuildfixSourceReport,
11 #[serde(default)]
12 pub fixes: Vec<BuildfixFixAction>,
13 #[serde(skip_serializing_if = "Option::is_none")]
14 pub metadata: Option<BuildfixMetadata>,
15}
16
17#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
18pub struct BuildfixSourceReport {
19 pub tool: String,
20 pub report_path: String,
21 #[serde(skip_serializing_if = "Option::is_none")]
22 pub report_schema: Option<String>,
23}
24
25#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
26pub struct BuildfixFixAction {
27 pub finding_ref: BuildfixFindingRef,
28 pub action: BuildfixAction,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub confidence: Option<BuildfixConfidence>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 pub requires_review: Option<bool>,
33}
34
35#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
36pub struct BuildfixFindingRef {
37 #[serde(skip_serializing_if = "Option::is_none")]
38 pub tool: Option<String>,
39 pub check_id: String,
40 pub code: String,
41 #[serde(skip_serializing_if = "Option::is_none")]
42 pub fingerprint: Option<String>,
43 #[serde(skip_serializing_if = "Option::is_none")]
44 pub location: Option<BuildfixLocation>,
45 #[serde(skip_serializing_if = "Option::is_none")]
46 pub safety: Option<BuildfixSafety>,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub preconditions: Option<BuildfixPreconditions>,
49}
50
51#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
52#[serde(rename_all = "snake_case")]
53pub enum BuildfixSafety {
54 Safe,
55 ReviewRequired,
56 Unsafe,
57}
58
59#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
60pub struct BuildfixPreconditions {
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub commit_sha: Option<String>,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 pub receipt_hash: Option<String>,
65}
66
67#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
68pub struct BuildfixLocation {
69 #[serde(skip_serializing_if = "Option::is_none")]
70 pub path: Option<String>,
71 #[serde(skip_serializing_if = "Option::is_none")]
72 pub line: Option<u32>,
73 #[serde(skip_serializing_if = "Option::is_none")]
74 pub col: Option<u32>,
75}
76
77#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
78pub struct BuildfixAction {
79 #[serde(rename = "type")]
80 pub action_type: BuildfixActionType,
81 #[serde(skip_serializing_if = "Option::is_none")]
82 pub target: Option<BuildfixActionTarget>,
83 #[serde(skip_serializing_if = "Option::is_none")]
84 pub content: Option<String>,
85 #[serde(skip_serializing_if = "Option::is_none")]
86 pub command: Option<String>,
87 #[serde(skip_serializing_if = "Option::is_none")]
88 pub description: Option<String>,
89}
90
91#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
92#[serde(rename_all = "lowercase")]
93pub enum BuildfixActionType {
94 Replace,
95 Insert,
96 Delete,
97 Command,
98}
99
100#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
101pub struct BuildfixActionTarget {
102 #[serde(skip_serializing_if = "Option::is_none")]
103 pub path: Option<String>,
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub line_start: Option<u32>,
106 #[serde(skip_serializing_if = "Option::is_none")]
107 pub line_end: Option<u32>,
108 #[serde(skip_serializing_if = "Option::is_none")]
109 pub col_start: Option<u32>,
110 #[serde(skip_serializing_if = "Option::is_none")]
111 pub col_end: Option<u32>,
112 #[serde(skip_serializing_if = "Option::is_none")]
113 pub pattern: Option<String>,
114}
115
116#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
117#[serde(rename_all = "lowercase")]
118pub enum BuildfixConfidence {
119 High,
120 Medium,
121 Low,
122}
123
124#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
125pub struct BuildfixMetadata {
126 #[serde(skip_serializing_if = "Option::is_none")]
127 pub generated_at: Option<String>,
128 #[serde(skip_serializing_if = "Option::is_none")]
129 pub generator: Option<String>,
130 #[serde(skip_serializing_if = "Option::is_none")]
131 pub dry_run: Option<bool>,
132}