memscope_rs/capture/inference/
mod.rs1use serde::{Deserialize, Serialize};
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
21pub enum DataSource {
22 Captured,
24 Inferred,
26 UserProvided,
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
32pub enum Confidence {
33 High,
35 Medium,
37 Low,
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct InferredBorrowInfo {
44 pub immutable_borrows: usize,
45 pub mutable_borrows: usize,
46 pub max_concurrent_borrows: usize,
47
48 pub _source: DataSource,
50 pub _confidence: Confidence,
52 pub _rule: &'static str,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct InferredSmartPointerInfo {
59 pub pointer_type: SmartPointerType,
60 pub ref_count: Option<usize>,
61 pub is_shared: bool,
62
63 pub _source: DataSource,
65 pub _confidence: Confidence,
67 pub _rule: &'static str,
69}
70
71#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
72pub enum SmartPointerType {
73 Rc,
74 Arc,
75 Box,
76 Unknown,
77}
78
79pub struct InferenceEngine {
81 rules: Vec<InferenceRule>,
82}
83
84#[derive(Debug, Clone)]
85pub struct InferenceRule {
86 pub name: &'static str,
87 pub description: &'static str,
88 pub confidence: Confidence,
89}
90
91impl InferenceEngine {
92 pub fn new() -> Self {
93 Self {
94 rules: vec![
95 InferenceRule {
96 name: "type_name_pattern",
97 description: "Infer from type name patterns (e.g., 'Rc<T>' → smart pointer)",
98 confidence: Confidence::Medium,
99 },
100 InferenceRule {
101 name: "size_heuristic",
102 description: "Infer from allocation size (e.g., 24 bytes → likely String)",
103 confidence: Confidence::Low,
104 },
105 InferenceRule {
106 name: "usage_pattern",
107 description: "Infer from usage patterns (e.g., multiple clones → shared)",
108 confidence: Confidence::Medium,
109 },
110 ],
111 }
112 }
113
114 pub fn infer_borrow_info(&self, type_name: Option<&str>) -> InferredBorrowInfo {
116 let (immutable, mutable, max_concurrent, confidence) = match type_name {
117 Some(name) if name.contains("Rc<") || name.contains("Arc<") => {
118 (5, 0, 5, Confidence::Low)
119 }
120 Some(name) if name.contains("Vec<") || name.contains("String") => {
121 (4, 2, 3, Confidence::Low)
122 }
123 Some(name) if name.contains("Box<") => (2, 1, 1, Confidence::Low),
124 _ => (0, 0, 0, Confidence::Low),
125 };
126
127 InferredBorrowInfo {
128 immutable_borrows: immutable,
129 mutable_borrows: mutable,
130 max_concurrent_borrows: max_concurrent,
131 _source: DataSource::Inferred,
132 _confidence: confidence,
133 _rule: "type_name_pattern",
134 }
135 }
136
137 pub fn infer_smart_pointer(&self, type_name: Option<&str>) -> InferredSmartPointerInfo {
139 let (ptr_type, is_shared, confidence) = match type_name {
140 Some(name) if name.contains("Rc<") => (SmartPointerType::Rc, true, Confidence::Medium),
141 Some(name) if name.contains("Arc<") => {
142 (SmartPointerType::Arc, true, Confidence::Medium)
143 }
144 Some(name) if name.contains("Box<") => {
145 (SmartPointerType::Box, false, Confidence::Medium)
146 }
147 _ => (SmartPointerType::Unknown, false, Confidence::Low),
148 };
149
150 InferredSmartPointerInfo {
151 pointer_type: ptr_type,
152 ref_count: if is_shared { Some(2) } else { None },
153 is_shared,
154 _source: DataSource::Inferred,
155 _confidence: confidence,
156 _rule: "type_name_pattern",
157 }
158 }
159
160 pub fn rules(&self) -> &[InferenceRule] {
162 &self.rules
163 }
164}
165
166impl Default for InferenceEngine {
167 fn default() -> Self {
168 Self::new()
169 }
170}
171
172#[cfg(test)]
173mod tests {
174 use super::*;
175
176 #[test]
177 fn test_infer_borrow_info_rc() {
178 let engine = InferenceEngine::new();
179 let info = engine.infer_borrow_info(Some("std::rc::Rc<String>"));
180
181 assert_eq!(info._source, DataSource::Inferred);
182 assert_eq!(info._confidence, Confidence::Low);
183 assert!(info.immutable_borrows > 0);
184 }
185
186 #[test]
187 fn test_infer_smart_pointer_arc() {
188 let engine = InferenceEngine::new();
189 let info = engine.infer_smart_pointer(Some("std::sync::Arc<Vec<u8>>"));
190
191 assert_eq!(info.pointer_type, SmartPointerType::Arc);
192 assert!(info.is_shared);
193 assert_eq!(info._source, DataSource::Inferred);
194 }
195
196 #[test]
197 fn test_infer_unknown_type() {
198 let engine = InferenceEngine::new();
199 let info = engine.infer_borrow_info(None);
200
201 assert_eq!(info.immutable_borrows, 0);
202 assert_eq!(info._confidence, Confidence::Low);
203 }
204}