ai_coding_shield/
types.rs1use serde::{Deserialize, Serialize};
2use std::path::PathBuf;
3
4#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6pub enum ArtifactType {
7 Workflow,
8 Skill,
9 McpInfo,
10 Rule,
11 Mcp,
12 Script,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct Artifact {
18 pub artifact_type: ArtifactType,
19 pub path: PathBuf,
20 pub content: String,
21 pub metadata: ArtifactMetadata,
22}
23
24#[derive(Debug, Clone, Default, Serialize, Deserialize)]
26pub struct ArtifactMetadata {
27 pub name: Option<String>,
28 pub description: Option<String>,
29 pub has_auto_run: bool,
30 pub has_turbo_annotation: bool,
31 pub commands: Vec<String>,
32 pub permissions: Vec<String>,
33}
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
37pub enum RiskLevel {
38 Low = 1,
39 Medium = 2,
40 High = 3,
41 Critical = 4,
42}
43
44impl RiskLevel {
45 pub fn as_str(&self) -> &str {
46 match self {
47 RiskLevel::Low => "LOW",
48 RiskLevel::Medium => "MEDIUM",
49 RiskLevel::High => "HIGH",
50 RiskLevel::Critical => "CRITICAL",
51 }
52 }
53
54 #[allow(dead_code)]
55 pub fn from_str(s: &str) -> Option<Self> {
56 match s.to_lowercase().as_str() {
57 "low" => Some(RiskLevel::Low),
58 "medium" => Some(RiskLevel::Medium),
59 "high" => Some(RiskLevel::High),
60 "critical" => Some(RiskLevel::Critical),
61 _ => None,
62 }
63 }
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize)]
68pub struct Finding {
69 pub artifact_path: PathBuf,
70 pub threat_id: String,
71 pub threat_name: String,
72 pub risk_level: RiskLevel,
73 pub risk_score: u8,
74 pub line_number: Option<usize>,
75 pub matched_pattern: String,
76 pub description: String,
77 pub recommendation: String,
78 pub mitre_id: Option<String>,
79 pub cwe_id: Option<String>,
80 pub flags: Vec<String>,
81}
82
83#[derive(Debug, Clone, Serialize, Deserialize)]
85pub struct AnalysisResult {
86 pub artifact: Artifact,
87 pub findings: Vec<Finding>,
88 pub overall_risk_score: u8,
89 pub risk_level: RiskLevel,
90}
91
92impl AnalysisResult {
93 pub fn new(artifact: Artifact) -> Self {
94 Self {
95 artifact,
96 findings: Vec::new(),
97 overall_risk_score: 0,
98 risk_level: RiskLevel::Low,
99 }
100 }
101
102 pub fn add_finding(&mut self, finding: Finding) {
103 self.overall_risk_score = self.overall_risk_score.saturating_add(finding.risk_score);
104 self.risk_level = self.risk_level.max(finding.risk_level);
105 self.findings.push(finding);
106 }
107}