testlint_sdk/profiler/
common_format.rs

1#![allow(dead_code)]
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6#[derive(Debug, Serialize, Deserialize, Clone)]
7pub struct CommonProfileData {
8    pub language: String,
9    pub source_file: String,
10    pub timestamp: String,
11
12    pub static_analysis: StaticMetrics,
13
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub runtime_analysis: Option<RuntimeMetrics>,
16}
17
18#[derive(Debug, Serialize, Deserialize, Clone)]
19pub struct StaticMetrics {
20    pub file_size_bytes: usize,
21    pub line_count: usize,
22    pub function_count: usize,
23    pub class_count: usize,
24    pub import_count: usize,
25    pub complexity_score: u32,
26}
27
28#[derive(Debug, Serialize, Deserialize, Clone)]
29pub struct RuntimeMetrics {
30    pub total_samples: u64,
31    pub execution_duration_secs: u64,
32    pub functions_executed: usize,
33
34    pub function_stats: HashMap<String, FunctionStats>,
35
36    pub hot_functions: Vec<HotFunction>,
37}
38
39#[derive(Debug, Serialize, Deserialize, Clone)]
40pub struct FunctionStats {
41    pub name: String,
42    pub execution_count: u64,
43    pub percentage: f64,
44
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub line_number: Option<usize>,
47
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub file_path: Option<String>,
50}
51
52#[derive(Debug, Serialize, Deserialize, Clone)]
53pub struct HotFunction {
54    pub rank: usize,
55    pub name: String,
56    pub samples: u64,
57    pub percentage: f64,
58}
59
60impl CommonProfileData {
61    pub fn to_json(&self) -> Result<String, serde_json::Error> {
62        serde_json::to_string(self)
63    }
64
65    pub fn to_json_pretty(&self) -> Result<String, serde_json::Error> {
66        serde_json::to_string_pretty(self)
67    }
68
69    pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
70        serde_json::from_str(json)
71    }
72
73    pub fn to_json_file(&self, path: &str) -> Result<(), std::io::Error> {
74        let json = self.to_json().map_err(std::io::Error::other)?;
75        std::fs::write(path, json)
76    }
77
78    pub fn from_json_file(path: &str) -> Result<Self, std::io::Error> {
79        let content = std::fs::read_to_string(path)?;
80        Self::from_json(&content)
81            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
82    }
83
84    pub fn to_protobuf(&self) -> crate::proto::ProfileData {
85        use crate::proto;
86
87        proto::ProfileData {
88            language: self.language.clone(),
89            source_file: self.source_file.clone(),
90            timestamp: self.timestamp.clone(),
91            static_analysis: Some(proto::StaticMetrics {
92                file_size_bytes: self.static_analysis.file_size_bytes as u64,
93                line_count: self.static_analysis.line_count as u64,
94                function_count: self.static_analysis.function_count as u64,
95                class_count: self.static_analysis.class_count as u64,
96                import_count: self.static_analysis.import_count as u64,
97                complexity_score: self.static_analysis.complexity_score,
98            }),
99            runtime_analysis: self
100                .runtime_analysis
101                .as_ref()
102                .map(|rt| proto::RuntimeMetrics {
103                    total_samples: rt.total_samples,
104                    execution_duration_secs: rt.execution_duration_secs,
105                    functions_executed: rt.functions_executed as u64,
106                    function_stats: rt
107                        .function_stats
108                        .values()
109                        .map(|stats| proto::FunctionStats {
110                            name: stats.name.clone(),
111                            execution_count: stats.execution_count,
112                            total_time_ms: 0, // Not tracked in current format
113                            avg_time_ms: 0.0, // Not tracked in current format
114                            samples: 0,       // Not tracked in current format
115                        })
116                        .collect(),
117                    hot_functions: rt
118                        .hot_functions
119                        .iter()
120                        .map(|hf| proto::HotFunction {
121                            name: hf.name.clone(),
122                            file: String::new(), // Extract from name if needed
123                            line: 0,             // Not available in current format
124                            samples: hf.samples,
125                            percentage: hf.percentage,
126                        })
127                        .collect(),
128                }),
129        }
130    }
131}
132
133impl std::fmt::Display for CommonProfileData {
134    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
135        writeln!(f, "=== Profile Data for {} ===", self.language)?;
136        writeln!(f, "Source: {}", self.source_file)?;
137        writeln!(f, "Timestamp: {}", self.timestamp)?;
138        writeln!(f)?;
139
140        writeln!(f, "Static Analysis:")?;
141        writeln!(
142            f,
143            "  File Size: {} bytes",
144            self.static_analysis.file_size_bytes
145        )?;
146        writeln!(f, "  Lines: {}", self.static_analysis.line_count)?;
147        writeln!(f, "  Functions: {}", self.static_analysis.function_count)?;
148        writeln!(f, "  Classes: {}", self.static_analysis.class_count)?;
149        writeln!(f, "  Imports: {}", self.static_analysis.import_count)?;
150        writeln!(f, "  Complexity: {}", self.static_analysis.complexity_score)?;
151
152        if let Some(runtime) = &self.runtime_analysis {
153            writeln!(f)?;
154            writeln!(f, "Runtime Analysis:")?;
155            writeln!(f, "  Duration: {} seconds", runtime.execution_duration_secs)?;
156            writeln!(f, "  Total Samples: {}", runtime.total_samples)?;
157            writeln!(f, "  Functions Executed: {}", runtime.functions_executed)?;
158            writeln!(f)?;
159            writeln!(f, "  Top Hot Functions:")?;
160            for hot in &runtime.hot_functions {
161                writeln!(
162                    f,
163                    "    {}. {} - {} samples ({:.2}%)",
164                    hot.rank, hot.name, hot.samples, hot.percentage
165                )?;
166            }
167        }
168
169        Ok(())
170    }
171}