Skip to main content

memscope_rs/capture/inference/
mod.rs

1//! Inference Engine for memscope-rs
2//!
3//! This module provides inference capabilities for data that cannot be
4//! captured at runtime. All inferred data is clearly marked with its
5//! source and confidence level.
6//!
7//! # Important Warning
8//!
9//! ⚠️ Inferred data may be WRONG. Use with caution.
10//!
11//! # Design Principles
12//!
13//! 1. All inferred data is marked with `_source: "inferred"`
14//! 2. Confidence level is provided for each inference
15//! 3. Inference rules are documented and configurable
16
17use serde::{Deserialize, Serialize};
18
19/// Source of data
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
21pub enum DataSource {
22    /// Real data captured at runtime
23    Captured,
24    /// Inferred data (may be wrong)
25    Inferred,
26    /// User-provided data
27    UserProvided,
28}
29
30/// Confidence level for inferred data
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
32pub enum Confidence {
33    /// High confidence (>80% accuracy expected)
34    High,
35    /// Medium confidence (50-80% accuracy expected)
36    Medium,
37    /// Low confidence (<50% accuracy expected)
38    Low,
39}
40
41/// Inferred borrow information
42#[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    /// Source of this data
49    pub _source: DataSource,
50    /// Confidence level
51    pub _confidence: Confidence,
52    /// Inference rule used
53    pub _rule: &'static str,
54}
55
56/// Inferred smart pointer information
57#[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    /// Source of this data
64    pub _source: DataSource,
65    /// Confidence level
66    pub _confidence: Confidence,
67    /// Inference rule used
68    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
79/// Inference Engine
80pub 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    /// Infer borrow information from type name
115    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    /// Infer smart pointer information from type name
138    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    /// Get all inference rules
161    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}