use agcodex_ast::Language;
pub use agcodex_ast::SourceLocation;
use serde::Deserialize;
use serde::Serialize;
use std::collections::HashMap;
use std::ops::Range;
use std::path::PathBuf;
use std::time::Duration;
use std::time::SystemTime;
use uuid::Uuid;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComprehensiveToolOutput<T> {
pub result: T,
pub context: OperationContext,
pub changes: Vec<Change>,
pub metadata: OperationMetadata,
pub summary: String,
pub performance: PerformanceMetrics,
pub diagnostics: Vec<Diagnostic>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OperationContext {
pub before: ContextSnapshot,
pub after: Option<ContextSnapshot>,
pub surrounding: Vec<ContextLine>,
pub location: SourceLocation,
pub scope: OperationScope,
pub language_context: Option<LanguageContext>,
pub project_context: Option<ProjectContext>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ContextSnapshot {
pub content: String,
pub timestamp: SystemTime,
pub content_hash: String,
pub ast_summary: Option<ComprehensiveAstSummary>,
pub symbols: Vec<ComprehensiveSymbol>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ContextLine {
pub line_number: usize,
pub content: String,
pub line_type: ContextLineType,
pub indentation: usize,
pub modified: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ContextLineType {
Before,
After,
Changed,
Added,
Removed,
Separator,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Change {
pub id: Uuid,
pub kind: ChangeKind,
pub old: Option<String>,
pub new: Option<String>,
pub line_range: Range<usize>,
pub char_range: Range<usize>,
pub location: SourceLocation,
pub semantic_impact: ComprehensiveSemanticImpact,
pub affected_symbols: Vec<String>,
pub confidence: f32,
pub description: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ChangeKind {
Added {
reason: String,
insertion_point: SourceLocation,
},
Modified {
why: String,
modification_type: ModificationType,
},
Deleted {
justification: String,
preservation_note: Option<String>,
},
Refactored {
from_pattern: String,
to_pattern: String,
refactor_type: RefactorType,
},
Moved {
from: SourceLocation,
to: SourceLocation,
move_reason: String,
},
Renamed {
old_name: String,
new_name: String,
symbol_type: String,
},
ImportChanged {
import_type: ImportChangeType,
module_name: String,
impact: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ModificationType {
Replacement,
ParameterChange,
TypeChange,
LogicEnhancement,
Optimization,
BugFix,
Formatting,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RefactorType {
ExtractMethod,
InlineMethod,
MoveMethod,
RenameSymbol,
ExtractVariable,
ExtractConstant,
ChangeSignature,
LambdaConversion,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ImportChangeType {
Added,
Removed,
Modified,
Reorganized,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComprehensiveSemanticImpact {
pub level: ImpactLevel,
pub scope: ImpactScope,
pub breaking_changes: Vec<BreakingChange>,
pub api_compatibility: ApiCompatibility,
pub performance_impact: ComprehensivePerformanceImpact,
pub security_impact: SecurityImpact,
pub test_impact: TestImpact,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ImpactLevel {
None,
Local,
Interface,
Architectural,
Critical,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ImpactScope {
Statement,
Function,
Class,
Module,
Package,
Project,
Dependencies,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BreakingChange {
pub description: String,
pub affected_apis: Vec<String>,
pub migration_strategy: Option<String>,
pub severity: BreakingSeverity,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum BreakingSeverity {
Minor,
Major,
Critical,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApiCompatibility {
pub backward_compatible: bool,
pub version_impact: VersionImpact,
pub deprecated_usage: Vec<String>,
pub new_features: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum VersionImpact {
Patch,
Minor,
Major,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComprehensivePerformanceImpact {
pub expected_change: PerformanceChange,
pub complexity_change: Option<ComplexityChange>,
pub memory_impact: MemoryImpact,
pub cpu_impact: String,
pub io_impact: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PerformanceChange {
Improvement(String),
Neutral,
Degradation(String),
Unknown,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComplexityChange {
pub time_complexity: (String, String),
pub space_complexity: (String, String),
pub cyclomatic_complexity_delta: i32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryImpact {
pub estimated_bytes_delta: Option<i64>,
pub allocation_changes: Vec<String>,
pub leak_risks: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecurityImpact {
pub level: SecurityLevel,
pub vulnerabilities: Vec<SecurityVulnerability>,
pub improvements: Vec<String>,
pub requires_review: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SecurityLevel {
None,
Low,
Medium,
High,
Critical,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecurityVulnerability {
pub vulnerability_type: String,
pub description: String,
pub severity: SecurityLevel,
pub mitigation: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TestImpact {
pub affected_tests: Vec<String>,
pub required_tests: Vec<String>,
pub coverage_impact: CoverageImpact,
pub test_categories: Vec<TestCategory>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CoverageImpact {
pub coverage_delta: Option<f32>,
pub uncovered_lines: Vec<usize>,
pub recommendations: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TestCategory {
Unit,
Integration,
EndToEnd,
Performance,
Security,
Regression,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OperationScope {
pub scope_type: ScopeType,
pub name: String,
pub path: Vec<String>,
pub file_path: PathBuf,
pub line_range: Range<usize>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ScopeType {
Global,
File,
Namespace,
Class,
Function,
Block,
Expression,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LanguageContext {
pub language: Language,
pub version: Option<String>,
pub features: Vec<String>,
pub frameworks: Vec<String>,
pub runtime_context: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProjectContext {
pub name: Option<String>,
pub project_type: Option<String>,
pub build_system: Option<String>,
pub dependencies: Vec<DependencyInfo>,
pub config_files: Vec<PathBuf>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DependencyInfo {
pub name: String,
pub version: Option<String>,
pub dependency_type: String,
pub change_type: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OperationMetadata {
pub tool: String,
pub operation: String,
pub operation_id: Uuid,
pub started_at: SystemTime,
pub completed_at: SystemTime,
pub confidence: f32,
pub parameters: HashMap<String, String>,
pub tool_version: String,
pub initiated_by: Option<String>,
pub session_id: Option<Uuid>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceMetrics {
pub execution_time: Duration,
pub phase_times: HashMap<String, Duration>,
pub memory_usage: MemoryUsage,
pub cpu_usage: CpuUsage,
pub io_stats: IoStats,
pub cache_stats: CacheStats,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryUsage {
pub peak_bytes: u64,
pub average_bytes: u64,
pub allocations: u64,
pub deallocations: u64,
pub efficiency_score: f32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CpuUsage {
pub cpu_time: Duration,
pub utilization_percent: f32,
pub context_switches: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IoStats {
pub bytes_read: u64,
pub bytes_written: u64,
pub read_ops: u64,
pub write_ops: u64,
pub io_wait_time: Duration,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheStats {
pub hit_rate: f32,
pub hits: u64,
pub misses: u64,
pub cache_size: u64,
pub efficiency_score: f32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Diagnostic {
pub level: DiagnosticLevel,
pub message: String,
pub location: Option<SourceLocation>,
pub _code: Option<String>,
pub suggestions: Vec<String>,
pub related: Vec<Uuid>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DiagnosticLevel {
Info,
Warning,
Error,
Hint,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComprehensiveAstSummary {
pub root_type: String,
pub node_count: usize,
pub max_depth: usize,
pub symbols: Vec<ComprehensiveSymbol>,
pub complexity: ComplexityMetrics,
pub ast_hash: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComprehensiveSymbol {
pub name: String,
pub symbol_type: SymbolType,
pub location: SourceLocation,
pub visibility: Visibility,
pub signature: Option<String>,
pub documentation: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SymbolType {
Function,
Method,
Class,
Struct,
Interface,
Trait,
Variable,
Constant,
Type,
Macro,
Module,
Namespace,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Visibility {
Public,
Private,
Protected,
Internal,
PackagePrivate,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComplexityMetrics {
pub cyclomatic: u32,
pub cognitive: u32,
pub halstead: Option<HalsteadMetrics>,
pub lines_of_code: u32,
pub function_count: u32,
pub max_nesting_depth: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HalsteadMetrics {
pub distinct_operators: u32,
pub distinct_operands: u32,
pub total_operators: u32,
pub total_operands: u32,
pub vocabulary: u32,
pub length: u32,
pub volume: f64,
pub difficulty: f64,
pub effort: f64,
}
pub trait ResultExt<T, E> {
fn to_tool_output(
self,
tool: &'static str,
operation: String,
location: SourceLocation,
) -> ComprehensiveToolOutput<Option<T>>
where
E: std::fmt::Display;
}
impl<T, E> ResultExt<T, E> for Result<T, E> {
fn to_tool_output(
self,
tool: &'static str,
operation: String,
location: SourceLocation,
) -> ComprehensiveToolOutput<Option<T>>
where
E: std::fmt::Display,
{
match self {
Ok(value) => OutputBuilder::new(Some(value), tool, operation, location).build(),
Err(error) => OutputBuilder::new(None, tool, operation, location)
.error(error.to_string())
.confidence(0.0)
.build(),
}
}
}
impl<T> ComprehensiveToolOutput<T> {
pub fn new(result: T, tool: &str, operation: String, location: SourceLocation) -> Self {
let operation_id = Uuid::new_v4();
let now = SystemTime::now();
Self {
result,
context: OperationContext::minimal(location),
changes: Vec::new(),
metadata: OperationMetadata {
tool: tool.to_string(),
operation,
operation_id,
started_at: now,
completed_at: now,
confidence: 1.0,
parameters: HashMap::new(),
tool_version: "0.1.0".to_string(),
initiated_by: None,
session_id: None,
},
summary: "Operation completed successfully".to_string(),
performance: PerformanceMetrics::default(),
diagnostics: Vec::new(),
}
}
pub fn add_change(mut self, change: Change) -> Self {
self.changes.push(change);
self
}
pub fn add_changes(mut self, changes: Vec<Change>) -> Self {
self.changes.extend(changes);
self
}
pub fn add_diagnostic(mut self, diagnostic: Diagnostic) -> Self {
self.diagnostics.push(diagnostic);
self
}
pub fn with_summary(mut self, summary: String) -> Self {
self.summary = summary;
self
}
pub const fn with_confidence(mut self, confidence: f32) -> Self {
self.metadata.confidence = confidence.clamp(0.0, 1.0);
self
}
pub fn has_errors(&self) -> bool {
self.diagnostics
.iter()
.any(|d| matches!(d.level, DiagnosticLevel::Error))
}
pub fn has_warnings(&self) -> bool {
self.diagnostics
.iter()
.any(|d| matches!(d.level, DiagnosticLevel::Warning))
}
pub fn max_impact_level(&self) -> ImpactLevel {
self.changes
.iter()
.map(|c| &c.semantic_impact.level)
.max_by_key(|level| match level {
ImpactLevel::None => 0,
ImpactLevel::Local => 1,
ImpactLevel::Interface => 2,
ImpactLevel::Architectural => 3,
ImpactLevel::Critical => 4,
})
.cloned()
.unwrap_or(ImpactLevel::None)
}
}
impl OperationContext {
pub fn minimal(location: SourceLocation) -> Self {
Self {
before: ContextSnapshot::empty(),
after: None,
surrounding: Vec::new(),
location,
scope: OperationScope::minimal(),
language_context: None,
project_context: None,
}
}
}
impl ContextSnapshot {
pub fn empty() -> Self {
Self {
content: String::new(),
timestamp: SystemTime::now(),
content_hash: "empty".to_string(),
ast_summary: None,
symbols: Vec::new(),
}
}
}
impl OperationScope {
pub fn minimal() -> Self {
Self {
scope_type: ScopeType::Global,
name: "global".to_string(),
path: vec!["global".to_string()],
file_path: PathBuf::new(),
line_range: 0..0,
}
}
}
impl Default for PerformanceMetrics {
fn default() -> Self {
Self {
execution_time: Duration::from_millis(0),
phase_times: HashMap::new(),
memory_usage: MemoryUsage::default(),
cpu_usage: CpuUsage::default(),
io_stats: IoStats::default(),
cache_stats: CacheStats::default(),
}
}
}
impl Default for MemoryUsage {
fn default() -> Self {
Self {
peak_bytes: 0,
average_bytes: 0,
allocations: 0,
deallocations: 0,
efficiency_score: 1.0,
}
}
}
impl Default for CpuUsage {
fn default() -> Self {
Self {
cpu_time: Duration::from_millis(0),
utilization_percent: 0.0,
context_switches: 0,
}
}
}
impl Default for IoStats {
fn default() -> Self {
Self {
bytes_read: 0,
bytes_written: 0,
read_ops: 0,
write_ops: 0,
io_wait_time: Duration::from_millis(0),
}
}
}
impl Default for CacheStats {
fn default() -> Self {
Self {
hit_rate: 0.0,
hits: 0,
misses: 0,
cache_size: 0,
efficiency_score: 0.0,
}
}
}
impl Change {
pub fn addition(location: SourceLocation, content: String, reason: String) -> Self {
Self {
id: Uuid::new_v4(),
kind: ChangeKind::Added {
reason,
insertion_point: location.clone(),
},
old: None,
new: Some(content),
line_range: location.start_line..location.start_line + 1,
char_range: location.start_column..location.start_column + 1,
location,
semantic_impact: ComprehensiveSemanticImpact::minimal(),
affected_symbols: Vec::new(),
confidence: 1.0,
description: "Content added".to_string(),
}
}
pub fn modification(
location: SourceLocation,
old_content: String,
new_content: String,
why: String,
) -> Self {
Self {
id: Uuid::new_v4(),
kind: ChangeKind::Modified {
why,
modification_type: ModificationType::Replacement,
},
old: Some(old_content),
new: Some(new_content),
line_range: location.start_line..location.start_line + 1,
char_range: location.start_column..location.start_column + 1,
location,
semantic_impact: ComprehensiveSemanticImpact::minimal(),
affected_symbols: Vec::new(),
confidence: 1.0,
description: "Content modified".to_string(),
}
}
pub fn deletion(location: SourceLocation, content: String, justification: String) -> Self {
Self {
id: Uuid::new_v4(),
kind: ChangeKind::Deleted {
justification,
preservation_note: None,
},
old: Some(content),
new: None,
line_range: location.start_line..location.start_line + 1,
char_range: location.start_column..location.start_column + 1,
location,
semantic_impact: ComprehensiveSemanticImpact::minimal(),
affected_symbols: Vec::new(),
confidence: 1.0,
description: "Content deleted".to_string(),
}
}
}
impl ComprehensiveSemanticImpact {
pub fn minimal() -> Self {
Self {
level: ImpactLevel::Local,
scope: ImpactScope::Statement,
breaking_changes: Vec::new(),
api_compatibility: ApiCompatibility::compatible(),
performance_impact: ComprehensivePerformanceImpact::neutral(),
security_impact: SecurityImpact::none(),
test_impact: TestImpact::minimal(),
}
}
}
impl ApiCompatibility {
pub const fn compatible() -> Self {
Self {
backward_compatible: true,
version_impact: VersionImpact::Patch,
deprecated_usage: Vec::new(),
new_features: Vec::new(),
}
}
}
impl ComprehensivePerformanceImpact {
pub fn neutral() -> Self {
Self {
expected_change: PerformanceChange::Neutral,
complexity_change: None,
memory_impact: MemoryImpact::neutral(),
cpu_impact: "No significant impact".to_string(),
io_impact: "No significant impact".to_string(),
}
}
}
impl MemoryImpact {
pub const fn neutral() -> Self {
Self {
estimated_bytes_delta: None,
allocation_changes: Vec::new(),
leak_risks: Vec::new(),
}
}
}
impl SecurityImpact {
pub const fn none() -> Self {
Self {
level: SecurityLevel::None,
vulnerabilities: Vec::new(),
improvements: Vec::new(),
requires_review: false,
}
}
}
impl TestImpact {
pub const fn minimal() -> Self {
Self {
affected_tests: Vec::new(),
required_tests: Vec::new(),
coverage_impact: CoverageImpact::neutral(),
test_categories: Vec::new(),
}
}
}
impl CoverageImpact {
pub const fn neutral() -> Self {
Self {
coverage_delta: None,
uncovered_lines: Vec::new(),
recommendations: Vec::new(),
}
}
}
impl Diagnostic {
pub const fn info(message: String) -> Self {
Self {
level: DiagnosticLevel::Info,
message,
location: None,
_code: None,
suggestions: Vec::new(),
related: Vec::new(),
}
}
pub const fn warning(message: String) -> Self {
Self {
level: DiagnosticLevel::Warning,
message,
location: None,
_code: None,
suggestions: Vec::new(),
related: Vec::new(),
}
}
pub const fn error(message: String) -> Self {
Self {
level: DiagnosticLevel::Error,
message,
location: None,
_code: None,
suggestions: Vec::new(),
related: Vec::new(),
}
}
pub fn with_suggestion(mut self, suggestion: String) -> Self {
self.suggestions.push(suggestion);
self
}
pub fn at_location(mut self, location: SourceLocation) -> Self {
self.location = Some(location);
self
}
pub fn with_code(mut self, code: String) -> Self {
self._code = Some(code);
self
}
}
pub struct OutputBuilder<T> {
result: T,
tool: String,
operation: String,
location: SourceLocation,
changes: Vec<Change>,
diagnostics: Vec<Diagnostic>,
confidence: f32,
summary: Option<String>,
context: Option<OperationContext>,
performance: Option<PerformanceMetrics>,
}
impl<T> OutputBuilder<T> {
pub fn new(result: T, tool: &str, operation: String, location: SourceLocation) -> Self {
Self {
result,
tool: tool.to_string(),
operation,
location,
changes: Vec::new(),
diagnostics: Vec::new(),
confidence: 1.0,
summary: None,
context: None,
performance: None,
}
}
pub fn change(mut self, change: Change) -> Self {
self.changes.push(change);
self
}
pub fn changes(mut self, changes: Vec<Change>) -> Self {
self.changes.extend(changes);
self
}
pub fn diagnostic(mut self, diagnostic: Diagnostic) -> Self {
self.diagnostics.push(diagnostic);
self
}
pub fn info(mut self, message: String) -> Self {
self.diagnostics.push(Diagnostic::info(message));
self
}
pub fn warning(mut self, message: String) -> Self {
self.diagnostics.push(Diagnostic::warning(message));
self
}
pub fn error(mut self, message: String) -> Self {
self.diagnostics.push(Diagnostic::error(message));
self
}
pub const fn confidence(mut self, confidence: f32) -> Self {
self.confidence = confidence.clamp(0.0, 1.0);
self
}
pub fn summary(mut self, summary: String) -> Self {
self.summary = Some(summary);
self
}
pub fn context(mut self, context: OperationContext) -> Self {
self.context = Some(context);
self
}
pub fn performance(mut self, performance: PerformanceMetrics) -> Self {
self.performance = Some(performance);
self
}
pub fn build(self) -> ComprehensiveToolOutput<T> {
let operation_id = Uuid::new_v4();
let now = SystemTime::now();
let summary = self.summary.unwrap_or_else(|| {
if self
.diagnostics
.iter()
.any(|d| matches!(d.level, DiagnosticLevel::Error))
{
"Operation completed with errors".to_string()
} else if self
.diagnostics
.iter()
.any(|d| matches!(d.level, DiagnosticLevel::Warning))
{
"Operation completed with warnings".to_string()
} else {
"Operation completed successfully".to_string()
}
});
ComprehensiveToolOutput {
result: self.result,
context: self
.context
.unwrap_or_else(|| OperationContext::minimal(self.location.clone())),
changes: self.changes,
metadata: OperationMetadata {
tool: self.tool,
operation: self.operation,
operation_id,
started_at: now,
completed_at: now,
confidence: self.confidence,
parameters: HashMap::new(),
tool_version: "0.1.0".to_string(),
initiated_by: None,
session_id: None,
},
summary,
performance: self.performance.unwrap_or_default(),
diagnostics: self.diagnostics,
}
}
}
pub struct ChangeBuilder {
location: SourceLocation,
old: Option<String>,
new: Option<String>,
description: Option<String>,
confidence: f32,
affected_symbols: Vec<String>,
impact: Option<ComprehensiveSemanticImpact>,
}
impl ChangeBuilder {
pub const fn new(location: SourceLocation) -> Self {
Self {
location,
old: None,
new: None,
description: None,
confidence: 1.0,
affected_symbols: Vec::new(),
impact: None,
}
}
pub fn old_content(mut self, content: String) -> Self {
self.old = Some(content);
self
}
pub fn new_content(mut self, content: String) -> Self {
self.new = Some(content);
self
}
pub fn description(mut self, description: String) -> Self {
self.description = Some(description);
self
}
pub const fn confidence(mut self, confidence: f32) -> Self {
self.confidence = confidence.clamp(0.0, 1.0);
self
}
pub fn symbol(mut self, symbol: String) -> Self {
self.affected_symbols.push(symbol);
self
}
pub fn impact(mut self, impact: ComprehensiveSemanticImpact) -> Self {
self.impact = Some(impact);
self
}
pub fn addition(self, reason: String) -> Change {
let description = self
.description
.unwrap_or_else(|| "Content added".to_string());
Change {
id: Uuid::new_v4(),
kind: ChangeKind::Added {
reason,
insertion_point: self.location.clone(),
},
old: self.old,
new: self.new,
line_range: self.location.start_line..self.location.start_line + 1,
char_range: self.location.start_column..self.location.start_column + 1,
location: self.location,
semantic_impact: self
.impact
.unwrap_or_else(ComprehensiveSemanticImpact::minimal),
affected_symbols: self.affected_symbols,
confidence: self.confidence,
description,
}
}
pub fn modification(self, why: String, modification_type: ModificationType) -> Change {
let description = self
.description
.unwrap_or_else(|| "Content modified".to_string());
Change {
id: Uuid::new_v4(),
kind: ChangeKind::Modified {
why,
modification_type,
},
old: self.old,
new: self.new,
line_range: self.location.start_line..self.location.start_line + 1,
char_range: self.location.start_column..self.location.start_column + 1,
location: self.location,
semantic_impact: self
.impact
.unwrap_or_else(ComprehensiveSemanticImpact::minimal),
affected_symbols: self.affected_symbols,
confidence: self.confidence,
description,
}
}
pub fn deletion(self, justification: String) -> Change {
let description = self
.description
.unwrap_or_else(|| "Content deleted".to_string());
Change {
id: Uuid::new_v4(),
kind: ChangeKind::Deleted {
justification,
preservation_note: None,
},
old: self.old,
new: self.new,
line_range: self.location.start_line..self.location.start_line + 1,
char_range: self.location.start_column..self.location.start_column + 1,
location: self.location,
semantic_impact: self
.impact
.unwrap_or_else(ComprehensiveSemanticImpact::minimal),
affected_symbols: self.affected_symbols,
confidence: self.confidence,
description,
}
}
}
pub fn simple_success<T>(
result: T,
tool: &'static str,
operation: String,
summary: String,
) -> ComprehensiveToolOutput<T> {
let location = SourceLocation::new("unknown", 0, 0, 0, 0, (0, 0));
OutputBuilder::new(result, tool, operation, location)
.summary(summary)
.build()
}
pub fn simple_error<T>(
result: T,
tool: &'static str,
operation: String,
error_message: String,
) -> ComprehensiveToolOutput<T> {
let location = SourceLocation::new("unknown", 0, 0, 0, 0, (0, 0));
OutputBuilder::new(result, tool, operation, location)
.error(error_message)
.confidence(0.0)
.build()
}
pub fn single_file_modification<T>(
result: T,
tool: &'static str,
operation: String,
file_path: &str,
line: usize,
column: usize,
old_content: String,
new_content: String,
reason: String,
) -> ComprehensiveToolOutput<T> {
let location = SourceLocation::new(file_path, line, column, line, column, (0, 0));
let change = ChangeBuilder::new(location.clone())
.old_content(old_content)
.new_content(new_content)
.modification(reason.clone(), ModificationType::Replacement);
OutputBuilder::new(result, tool, operation, location)
.change(change)
.summary(format!(
"Modified {} at line {}: {}",
file_path, line, reason
))
.build()
}
pub fn multi_file_changes<T>(
result: T,
tool: &'static str,
operation: String,
changes: Vec<Change>,
) -> ComprehensiveToolOutput<T> {
let location = if let Some(first_change) = changes.first() {
first_change.location.clone()
} else {
SourceLocation::new("unknown", 0, 0, 0, 0, (0, 0))
};
let summary = if changes.is_empty() {
"No changes made".to_string()
} else {
format!("Made {} changes across files", changes.len())
};
OutputBuilder::new(result, tool, operation, location)
.changes(changes)
.summary(summary)
.build()
}
pub struct PerformanceTimer {
started_at: SystemTime,
phase_times: HashMap<String, Duration>,
current_phase: Option<String>,
current_phase_start: Option<SystemTime>,
}
impl PerformanceTimer {
pub fn new() -> Self {
Self {
started_at: SystemTime::now(),
phase_times: HashMap::new(),
current_phase: None,
current_phase_start: None,
}
}
pub fn start_phase(&mut self, phase_name: String) {
self.current_phase = Some(phase_name);
self.current_phase_start = Some(SystemTime::now());
}
pub fn end_current_phase(&mut self) {
if let (Some(phase_name), Some(start_time)) =
(self.current_phase.take(), self.current_phase_start.take())
&& let Ok(duration) = start_time.elapsed()
{
self.phase_times.insert(phase_name, duration);
}
}
pub fn elapsed(&self) -> Duration {
self.started_at.elapsed().unwrap_or_default()
}
pub fn metrics(mut self) -> PerformanceMetrics {
self.end_current_phase();
let execution_time = self.started_at.elapsed().unwrap_or_default();
PerformanceMetrics {
execution_time,
phase_times: self.phase_times,
memory_usage: MemoryUsage::default(),
cpu_usage: CpuUsage::default(),
io_stats: IoStats::default(),
cache_stats: CacheStats::default(),
}
}
}
impl Default for PerformanceTimer {
fn default() -> Self {
Self::new()
}
}