use std::path::PathBuf;
#[derive(Debug, Clone, serde::Serialize)]
pub struct CallerDetail {
pub name: String,
#[serde(serialize_with = "crate::serialize_path_normalized")]
pub file: PathBuf,
#[serde(rename = "line_start")]
pub line: u32,
pub call_line: u32,
pub snippet: Option<String>,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct TestInfo {
pub name: String,
#[serde(serialize_with = "crate::serialize_path_normalized")]
pub file: PathBuf,
#[serde(rename = "line_start")]
pub line: u32,
pub call_depth: usize,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct TransitiveCaller {
pub name: String,
#[serde(serialize_with = "crate::serialize_path_normalized")]
pub file: PathBuf,
#[serde(rename = "line_start")]
pub line: u32,
pub depth: usize,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct TypeImpacted {
pub name: String,
#[serde(serialize_with = "crate::serialize_path_normalized")]
pub file: PathBuf,
#[serde(rename = "line_start")]
pub line: u32,
pub shared_types: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct ImpactResult {
pub function_name: String,
pub callers: Vec<CallerDetail>,
pub tests: Vec<TestInfo>,
pub transitive_callers: Vec<TransitiveCaller>,
pub type_impacted: Vec<TypeImpacted>,
pub degraded: bool,
}
impl serde::Serialize for ImpactResult {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeStruct;
let mut field_count = 6; field_count += 1; if !self.transitive_callers.is_empty() {
field_count += 1;
}
if self.degraded {
field_count += 1;
}
let mut state = serializer.serialize_struct("ImpactResult", field_count)?;
state.serialize_field("name", &self.function_name)?;
state.serialize_field("callers", &self.callers)?;
state.serialize_field("caller_count", &self.callers.len())?;
state.serialize_field("tests", &self.tests)?;
state.serialize_field("test_count", &self.tests.len())?;
if !self.transitive_callers.is_empty() {
state.serialize_field("transitive_callers", &self.transitive_callers)?;
}
state.serialize_field("type_impacted", &self.type_impacted)?;
state.serialize_field("type_impacted_count", &self.type_impacted.len())?;
if self.degraded {
state.serialize_field("degraded", &true)?;
}
state.end()
}
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct FunctionHints {
pub caller_count: usize,
pub test_count: usize,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct ChangedFunction {
pub name: String,
#[serde(serialize_with = "crate::serialize_path_normalized")]
pub file: PathBuf,
pub line_start: u32,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct DiffTestInfo {
pub name: String,
#[serde(serialize_with = "crate::serialize_path_normalized")]
pub file: PathBuf,
#[serde(rename = "line_start")]
pub line: u32,
pub via: String,
pub call_depth: usize,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct DiffImpactSummary {
pub changed_count: usize,
pub caller_count: usize,
pub test_count: usize,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub truncated: bool,
#[serde(skip_serializing_if = "is_zero_usize")]
pub truncated_functions: usize,
}
fn is_zero_usize(n: &usize) -> bool {
*n == 0
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct DiffImpactResult {
pub changed_functions: Vec<ChangedFunction>,
#[serde(rename = "callers")]
pub all_callers: Vec<CallerDetail>,
#[serde(rename = "tests")]
pub all_tests: Vec<DiffTestInfo>,
pub summary: DiffImpactSummary,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct TestSuggestion {
pub test_name: String,
#[serde(serialize_with = "crate::serialize_path_normalized")]
pub suggested_file: PathBuf,
pub for_function: String,
pub pattern_source: String,
pub inline: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
#[serde(rename_all = "lowercase")]
pub enum RiskLevel {
High,
Medium,
Low,
}
impl std::fmt::Display for RiskLevel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
RiskLevel::High => write!(f, "high"),
RiskLevel::Medium => write!(f, "medium"),
RiskLevel::Low => write!(f, "low"),
}
}
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct RiskScore {
pub caller_count: usize,
pub test_count: usize,
pub test_ratio: f32,
pub risk_level: RiskLevel,
pub blast_radius: RiskLevel,
pub score: f32,
}