use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Symbol {
pub symbol_id: String,
pub file_id: String,
pub path: String,
pub language: String,
pub name: String,
pub kind: String,
pub signature: Option<String>,
pub doc_comment: Option<String>,
pub visibility: Option<String>,
pub parent_symbol_id: Option<String>,
pub start_line: usize,
pub start_column: usize,
pub end_line: usize,
pub end_column: usize,
pub start_byte: usize,
pub end_byte: usize,
pub body_start_line: Option<usize>,
pub body_start_column: Option<usize>,
pub body_end_line: Option<usize>,
pub body_end_column: Option<usize>,
pub body_start_byte: Option<usize>,
pub body_end_byte: Option<usize>,
pub body_hash: Option<String>,
pub semantic_group: Option<String>,
pub is_test: bool,
pub test_container: bool,
}
impl Symbol {
pub fn hidden_body_line_count(&self) -> Option<usize> {
match (self.body_start_line, self.body_end_line) {
(Some(start), Some(end)) if end >= start => Some(end - start + 1),
_ => None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct FileFact {
pub file_id: String,
pub path: String,
pub language: String,
pub content_hash: String,
pub content_bytes: i64,
pub line_count: Option<i64>,
pub indexed_at: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ReferenceSite {
pub from_symbol_name: String,
pub from_symbol_id: String,
pub to_symbol_name: String,
pub kind: String,
pub path: String,
pub start_line: Option<usize>,
pub start_column: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub occurrences: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub target: Option<String>,
#[serde(skip)]
pub enclosing_symbol_name: Option<String>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
pub enum SiteLabel {
Proven,
Likely,
Unresolved,
Excluded,
}
impl SiteLabel {
pub const ALL: [SiteLabel; 4] = [
SiteLabel::Proven,
SiteLabel::Likely,
SiteLabel::Unresolved,
SiteLabel::Excluded,
];
pub fn as_str(self) -> &'static str {
match self {
SiteLabel::Proven => "proven",
SiteLabel::Likely => "likely",
SiteLabel::Unresolved => "unresolved",
SiteLabel::Excluded => "excluded",
}
}
pub fn rank(self) -> usize {
match self {
SiteLabel::Proven => 0,
SiteLabel::Likely => 1,
SiteLabel::Unresolved => 2,
SiteLabel::Excluded => 3,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct LabeledSite {
#[serde(flatten)]
pub site: ReferenceSite,
pub label: SiteLabel,
pub basis: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub end_line: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub arg_count: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct TextOnlyLines {
pub path: String,
pub lines: Vec<usize>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct TextScanSummary {
pub files_scanned: usize,
pub files_total: usize,
pub complete: bool,
pub elapsed_ms: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub skipped: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
pub struct ReferenceCounts {
pub sites: usize,
pub proven: usize,
pub likely: usize,
pub unresolved: usize,
pub excluded: usize,
pub text_lines: usize,
pub site_lines: usize,
pub definition_lines: usize,
pub import_lines: usize,
pub text_only_lines: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ReferenceTarget {
pub symbol_id: String,
pub name: String,
pub display_name: String,
pub kind: String,
pub path: String,
pub line: usize,
pub definitions_with_name: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct OverrideRow {
pub symbol_id: String,
pub owner: String,
pub name: String,
pub path: String,
pub line: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ConstructionSite {
pub path: String,
pub line: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct VariantUse {
pub caller: String,
pub caller_id: String,
pub path: String,
pub line: usize,
pub variants_used: usize,
pub variants_total: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Registration {
pub pattern_id: String,
pub verb: Option<String>,
pub template: Option<String>,
pub path: String,
pub line: usize,
pub by_name: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct CallingTest {
pub symbol_id: String,
pub name: String,
pub path: String,
pub line: usize,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub command: Option<String>,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub name_only: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ReferenceReport {
pub target: ReferenceTarget,
pub counts: ReferenceCounts,
pub sites: Vec<LabeledSite>,
pub text_only: Vec<TextOnlyLines>,
pub text_scan: TextScanSummary,
pub cannot_see: Vec<String>,
pub imports: Vec<(String, usize)>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub overrides: Vec<OverrideRow>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub overridden: Vec<OverrideRow>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub constructions: Vec<ConstructionSite>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub variant_uses: Vec<VariantUse>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub registrations: Vec<Registration>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub tests: Vec<CallingTest>,
}
pub(crate) fn has_generated_lambda_name(name: &str) -> bool {
name.strip_prefix("lambda_")
.is_some_and(|line| !line.is_empty() && line.bytes().all(|byte| byte.is_ascii_digit()))
}
pub(crate) fn is_generated_lambda_name(
name: &str,
language: &str,
kind: &str,
signature: Option<&str>,
) -> bool {
has_generated_lambda_name(name)
&& language == "python"
&& kind == "function"
&& signature.is_some_and(|signature| signature.starts_with("lambda"))
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct StructuralFact {
pub structural_fact_id: String,
pub path: String,
pub language: String,
pub pattern_id: String,
pub capture_name: String,
pub node_kind: String,
pub key: Option<String>,
pub metadata: Option<serde_json::Value>,
pub containing_symbol_name: Option<String>,
pub start_line: usize,
pub end_line: usize,
pub confidence: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct LiteralFact {
pub literal_id: String,
pub path: String,
pub literal_text: String,
pub kind: String,
pub carrier: Option<String>,
pub start_line: usize,
pub containing_symbol_name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct TypeFact {
pub type_fact_id: String,
pub symbol_id: String,
pub language: String,
pub resolved_type: String,
pub generic_params: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ContextSlice {
pub target_symbol: Symbol,
pub target_body: String,
pub callee_signatures: Vec<String>,
pub related_types: Vec<String>,
pub related_tests: Vec<Symbol>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct SymbolSearchResult {
pub symbol: Symbol,
pub score: f64,
pub snippet: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub explain: Option<SearchExplain>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct SearchExplain {
pub bm25: Option<f64>,
pub branches: Vec<String>,
pub name_tier: String,
pub name_strength: u32,
pub terms: Vec<(String, String, f64)>,
pub term_score: f64,
#[serde(default)]
pub field_diversity_bonus: f64,
pub name_bonus: f64,
pub kind_prior: f64,
pub path_role: f64,
pub documentation: f64,
pub test_intent: f64,
#[serde(default)]
pub nested: f64,
pub word_weights: Vec<(String, f64)>,
pub candidates: usize,
pub rerank_us: u128,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct BlastRadiusResult {
pub seed_type: String,
pub seeds: Vec<String>,
pub likely_tests: Vec<TestTarget>,
pub impacted_symbols: Vec<ImpactedSymbol>,
pub likely_tests_truncated: bool,
pub impacted_symbols_truncated: bool,
#[serde(default)]
pub traversal_ceiling_reached: bool,
#[serde(default)]
pub limit_at_maximum: bool,
#[serde(default)]
pub likely_tests_found: usize,
#[serde(default)]
pub impacted_symbols_found: usize,
#[serde(default)]
pub stopped_at_depth: Option<usize>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct TestTarget {
pub name: String,
pub path: String,
pub line: usize,
pub reason: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ImpactedSymbol {
pub name: String,
pub kind: String,
pub path: String,
pub line: usize,
pub depth: usize,
#[serde(skip)]
pub enclosing_symbol_name: Option<String>,
}