codegraph_parser_api/
metrics.rs1use serde::{Deserialize, Serialize};
2use std::time::Duration;
3
4#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6pub struct ParserMetrics {
7 pub files_attempted: usize,
9
10 pub files_succeeded: usize,
12
13 pub files_failed: usize,
15
16 #[serde(with = "duration_serde")]
18 pub total_parse_time: Duration,
19
20 pub total_entities: usize,
22
23 pub total_relationships: usize,
25
26 pub peak_memory_bytes: Option<usize>,
28}
29
30mod duration_serde {
32 use serde::{Deserialize, Deserializer, Serialize, Serializer};
33 use std::time::Duration;
34
35 pub fn serialize<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error>
36 where
37 S: Serializer,
38 {
39 duration.as_secs().serialize(serializer)
40 }
41
42 pub fn deserialize<'de, D>(deserializer: D) -> Result<Duration, D::Error>
43 where
44 D: Deserializer<'de>,
45 {
46 let secs: u64 = u64::deserialize(deserializer)?;
47 Ok(Duration::from_secs(secs))
48 }
49}
50
51impl Default for ParserMetrics {
52 fn default() -> Self {
53 Self {
54 files_attempted: 0,
55 files_succeeded: 0,
56 files_failed: 0,
57 total_parse_time: Duration::ZERO,
58 total_entities: 0,
59 total_relationships: 0,
60 peak_memory_bytes: None,
61 }
62 }
63}
64
65impl ParserMetrics {
66 pub fn success_rate(&self) -> f64 {
68 if self.files_attempted == 0 {
69 0.0
70 } else {
71 self.files_succeeded as f64 / self.files_attempted as f64
72 }
73 }
74
75 pub fn avg_parse_time(&self) -> Duration {
77 if self.files_succeeded == 0 {
78 Duration::ZERO
79 } else {
80 self.total_parse_time / self.files_succeeded as u32
81 }
82 }
83
84 pub fn avg_entities_per_file(&self) -> f64 {
86 if self.files_succeeded == 0 {
87 0.0
88 } else {
89 self.total_entities as f64 / self.files_succeeded as f64
90 }
91 }
92
93 pub fn merge(&mut self, other: &ParserMetrics) {
95 self.files_attempted += other.files_attempted;
96 self.files_succeeded += other.files_succeeded;
97 self.files_failed += other.files_failed;
98 self.total_parse_time += other.total_parse_time;
99 self.total_entities += other.total_entities;
100 self.total_relationships += other.total_relationships;
101
102 self.peak_memory_bytes = match (self.peak_memory_bytes, other.peak_memory_bytes) {
104 (Some(a), Some(b)) => Some(a.max(b)),
105 (Some(a), None) => Some(a),
106 (None, Some(b)) => Some(b),
107 (None, None) => None,
108 };
109 }
110}