1use crate::Trackable;
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11pub enum PointerInfo {
12 Real(usize),
14 Synthetic { ptr: usize, reason: SyntheticReason },
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
20pub enum SyntheticReason {
21 NoHeapAllocation,
23 EmptyContainer,
25 SmartPointerIndirection,
27 ComplexType,
29 InvalidPointer,
31}
32
33pub struct EnhancedPointerExtractor;
35
36impl EnhancedPointerExtractor {
37 pub fn extract_pointer_info<T: Trackable>(value: &T) -> PointerInfo {
39 match value.get_heap_ptr() {
40 Some(ptr) if Self::is_valid_heap_pointer(ptr) => PointerInfo::Real(ptr),
41 Some(ptr) if Self::is_synthetic_pointer(ptr) => {
42 let reason = Self::determine_synthetic_reason(ptr);
44 PointerInfo::Synthetic { ptr, reason }
45 }
46 Some(_ptr) => {
47 let synthetic = Self::generate_synthetic_pointer();
49 PointerInfo::Synthetic {
50 ptr: synthetic,
51 reason: SyntheticReason::InvalidPointer,
52 }
53 }
54 None => {
55 let synthetic = Self::generate_synthetic_pointer();
57 PointerInfo::Synthetic {
58 ptr: synthetic,
59 reason: SyntheticReason::NoHeapAllocation,
60 }
61 }
62 }
63 }
64
65 pub fn is_valid_heap_pointer(ptr: usize) -> bool {
67 if ptr < 0x1000 {
70 return false;
71 }
72
73 #[cfg(target_pointer_width = "64")]
75 {
76 if ptr > 0x7FFF_FFFF_FFFF_FFFF {
77 return false;
78 }
79 }
80
81 #[cfg(target_pointer_width = "32")]
82 {
83 if ptr > 0x7FFF_FFFF {
84 return false;
85 }
86 }
87
88 !Self::is_synthetic_pointer(ptr)
90 }
91
92 pub fn is_synthetic_pointer(ptr: usize) -> bool {
94 match ptr {
96 0x5000_0000..=0x5FFF_FFFF => true,
98 0x8000_0000..=0x8FFF_FFFF => true,
100 0x9000_0000..=0x9FFF_FFFF => true,
102 0xA000_0000..=0xFFFF_FFFF => true,
104 _ => false,
105 }
106 }
107
108 fn determine_synthetic_reason(ptr: usize) -> SyntheticReason {
110 match ptr {
111 0x5000_0000..=0x5FFF_FFFF => SyntheticReason::SmartPointerIndirection,
112 0x8000_0000..=0x8FFF_FFFF => SyntheticReason::NoHeapAllocation,
113 0x9000_0000..=0x9FFF_FFFF => SyntheticReason::NoHeapAllocation,
114 0xA000_0000..=0xFFFF_FFFF => SyntheticReason::ComplexType,
115 _ => SyntheticReason::InvalidPointer,
116 }
117 }
118
119 fn generate_synthetic_pointer() -> usize {
121 use std::sync::atomic::{AtomicUsize, Ordering};
122 static SYNTHETIC_COUNTER: AtomicUsize = AtomicUsize::new(0);
123
124 let id = SYNTHETIC_COUNTER.fetch_add(1, Ordering::Relaxed);
125 0x9000_0000 + (id % 0x0FFF_FFFF)
126 }
127
128 pub fn extract_vec_pointer<T>(vec: &Vec<T>) -> PointerInfo {
130 if vec.capacity() > 0 {
131 let ptr = vec.as_ptr() as usize;
132 if Self::is_valid_heap_pointer(ptr) {
133 PointerInfo::Real(ptr)
134 } else {
135 PointerInfo::Synthetic {
136 ptr: Self::generate_synthetic_pointer(),
137 reason: SyntheticReason::InvalidPointer,
138 }
139 }
140 } else {
141 PointerInfo::Synthetic {
142 ptr: Self::generate_synthetic_pointer(),
143 reason: SyntheticReason::EmptyContainer,
144 }
145 }
146 }
147
148 pub fn extract_string_pointer(string: &String) -> PointerInfo {
150 if string.capacity() > 0 {
151 let ptr = string.as_ptr() as usize;
152 if Self::is_valid_heap_pointer(ptr) {
153 PointerInfo::Real(ptr)
154 } else {
155 PointerInfo::Synthetic {
156 ptr: Self::generate_synthetic_pointer(),
157 reason: SyntheticReason::InvalidPointer,
158 }
159 }
160 } else {
161 PointerInfo::Synthetic {
162 ptr: Self::generate_synthetic_pointer(),
163 reason: SyntheticReason::EmptyContainer,
164 }
165 }
166 }
167
168 #[allow(clippy::borrowed_box)]
170 pub fn extract_box_pointer<T>(boxed: &Box<T>) -> PointerInfo {
171 let ptr = boxed.as_ref() as *const T as usize;
172 if Self::is_valid_heap_pointer(ptr) {
173 PointerInfo::Real(ptr)
174 } else {
175 PointerInfo::Synthetic {
176 ptr: Self::generate_synthetic_pointer(),
177 reason: SyntheticReason::InvalidPointer,
178 }
179 }
180 }
181
182 pub fn extract_hashmap_pointer<K, V, S>(
184 map: &std::collections::HashMap<K, V, S>,
185 ) -> PointerInfo {
186 if map.is_empty() {
187 PointerInfo::Synthetic {
188 ptr: Self::generate_synthetic_pointer(),
189 reason: SyntheticReason::EmptyContainer,
190 }
191 } else {
192 PointerInfo::Synthetic {
194 ptr: Self::generate_synthetic_pointer(),
195 reason: SyntheticReason::ComplexType,
196 }
197 }
198 }
199
200 pub fn get_pointer_statistics(pointers: &[PointerInfo]) -> PointerStatistics {
202 let mut real_count = 0;
203 let mut synthetic_count = 0;
204 let mut reason_counts = std::collections::HashMap::new();
205
206 for pointer in pointers {
207 match pointer {
208 PointerInfo::Real(_) => real_count += 1,
209 PointerInfo::Synthetic { reason, .. } => {
210 synthetic_count += 1;
211 *reason_counts.entry(reason.clone()).or_insert(0) += 1;
212 }
213 }
214 }
215
216 let total = pointers.len();
217 let real_ratio = if total > 0 {
218 real_count as f64 / total as f64
219 } else {
220 0.0
221 };
222
223 PointerStatistics {
224 total_pointers: total,
225 real_pointers: real_count,
226 synthetic_pointers: synthetic_count,
227 real_pointer_ratio: real_ratio,
228 synthetic_reasons: reason_counts,
229 }
230 }
231}
232
233#[derive(Debug, Clone, Serialize)]
235pub struct PointerStatistics {
236 pub total_pointers: usize,
237 pub real_pointers: usize,
238 pub synthetic_pointers: usize,
239 pub real_pointer_ratio: f64,
240 pub synthetic_reasons: std::collections::HashMap<SyntheticReason, usize>,
241}
242
243pub trait EnhancedTrackable {
245 fn get_pointer_info(&self) -> PointerInfo;
247
248 fn get_size_estimate(&self) -> usize;
250
251 fn get_type_info(&self) -> TypeInfo;
253}
254
255#[derive(Debug, Clone, Serialize, Deserialize)]
257pub struct TypeInfo {
258 pub type_name: String,
259 pub category: TypeCategory,
260 pub complexity_score: u32,
261 pub is_heap_allocated: bool,
262}
263
264#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
266pub enum TypeCategory {
267 Primitive,
268 Collection,
269 SmartPointer,
270 Complex,
271 Atomic,
272 Synchronization,
273 Custom,
274}
275
276impl<T> EnhancedTrackable for Vec<T> {
278 fn get_pointer_info(&self) -> PointerInfo {
279 EnhancedPointerExtractor::extract_vec_pointer(self)
280 }
281
282 fn get_size_estimate(&self) -> usize {
283 std::mem::size_of::<Vec<T>>() + (self.capacity() * std::mem::size_of::<T>())
284 }
285
286 fn get_type_info(&self) -> TypeInfo {
287 TypeInfo {
288 type_name: format!("Vec<{}>", std::any::type_name::<T>()),
289 category: TypeCategory::Collection,
290 complexity_score: 2,
291 is_heap_allocated: self.capacity() > 0,
292 }
293 }
294}
295
296impl EnhancedTrackable for String {
297 fn get_pointer_info(&self) -> PointerInfo {
298 EnhancedPointerExtractor::extract_string_pointer(self)
299 }
300
301 fn get_size_estimate(&self) -> usize {
302 std::mem::size_of::<String>() + self.capacity()
303 }
304
305 fn get_type_info(&self) -> TypeInfo {
306 TypeInfo {
307 type_name: "String".to_string(),
308 category: TypeCategory::Collection,
309 complexity_score: 1,
310 is_heap_allocated: self.capacity() > 0,
311 }
312 }
313}
314
315impl<T> EnhancedTrackable for Box<T> {
316 fn get_pointer_info(&self) -> PointerInfo {
317 EnhancedPointerExtractor::extract_box_pointer(self)
318 }
319
320 fn get_size_estimate(&self) -> usize {
321 std::mem::size_of::<Box<T>>() + std::mem::size_of::<T>()
322 }
323
324 fn get_type_info(&self) -> TypeInfo {
325 TypeInfo {
326 type_name: format!("Box<{}>", std::any::type_name::<T>()),
327 category: TypeCategory::SmartPointer,
328 complexity_score: 2,
329 is_heap_allocated: true,
330 }
331 }
332}
333
334#[cfg(test)]
335mod tests {
336 use super::*;
337 use std::thread;
338
339 #[test]
340 fn test_valid_heap_pointer_detection() {
341 assert!(EnhancedPointerExtractor::is_valid_heap_pointer(0x1000));
343 assert!(EnhancedPointerExtractor::is_valid_heap_pointer(0x7FFF_0000));
344
345 assert!(!EnhancedPointerExtractor::is_valid_heap_pointer(0));
347 assert!(!EnhancedPointerExtractor::is_valid_heap_pointer(0x100));
348
349 assert!(!EnhancedPointerExtractor::is_valid_heap_pointer(
351 0x8000_0000
352 ));
353 assert!(!EnhancedPointerExtractor::is_valid_heap_pointer(
354 0xA000_0000
355 ));
356 }
357
358 #[test]
359 fn test_synthetic_pointer_detection() {
360 assert!(EnhancedPointerExtractor::is_synthetic_pointer(0x5000_0000));
361 assert!(EnhancedPointerExtractor::is_synthetic_pointer(0x8000_0000));
362 assert!(EnhancedPointerExtractor::is_synthetic_pointer(0xA000_0000));
363
364 assert!(!EnhancedPointerExtractor::is_synthetic_pointer(0x1000));
365 assert!(!EnhancedPointerExtractor::is_synthetic_pointer(0x7FFF_0000));
366 }
367
368 #[test]
369 fn test_vec_pointer_extraction() {
370 let vec = vec![1, 2, 3, 4, 5];
371 let pointer_info = EnhancedPointerExtractor::extract_vec_pointer(&vec);
372
373 match pointer_info {
374 PointerInfo::Real(_) => {
375 }
377 PointerInfo::Synthetic { reason, .. } => {
378 panic!("Expected real pointer, got synthetic: {reason:?}");
379 }
380 }
381 }
382
383 #[test]
384 fn test_empty_vec_pointer_extraction() {
385 let vec: Vec<i32> = Vec::new();
386 let pointer_info = EnhancedPointerExtractor::extract_vec_pointer(&vec);
387
388 match pointer_info {
389 PointerInfo::Synthetic {
390 reason: SyntheticReason::EmptyContainer,
391 ..
392 } => {
393 }
395 _ => {
396 panic!("Expected synthetic pointer with EmptyContainer reason");
397 }
398 }
399 }
400
401 #[test]
402 fn test_enhanced_trackable_vec() {
403 let vec = vec![1, 2, 3];
404 let pointer_info = vec.get_pointer_info();
405 let size_estimate = Trackable::get_size_estimate(&vec);
406 let type_info = vec.get_type_info();
407
408 match pointer_info {
409 PointerInfo::Real(_) => {
410 }
412 _ => panic!("Expected real pointer for Vec with data"),
413 }
414
415 assert!(size_estimate > 0);
416 assert_eq!(type_info.category, TypeCategory::Collection);
417 assert!(type_info.is_heap_allocated);
418 }
419
420 #[test]
421 fn test_pointer_statistics() {
422 let pointers = vec![
423 PointerInfo::Real(0x1000),
424 PointerInfo::Real(0x2000),
425 PointerInfo::Synthetic {
426 ptr: 0x8000_0000,
427 reason: SyntheticReason::EmptyContainer,
428 },
429 PointerInfo::Synthetic {
430 ptr: 0x9000_0000,
431 reason: SyntheticReason::ComplexType,
432 },
433 ];
434
435 let stats = EnhancedPointerExtractor::get_pointer_statistics(&pointers);
436
437 assert_eq!(stats.total_pointers, 4);
438 assert_eq!(stats.real_pointers, 2);
439 assert_eq!(stats.synthetic_pointers, 2);
440 assert_eq!(stats.real_pointer_ratio, 0.5);
441 assert_eq!(stats.synthetic_reasons.len(), 2);
442 }
443
444 #[test]
445 fn test_boundary_pointer_values() {
446 assert!(!EnhancedPointerExtractor::is_valid_heap_pointer(0));
448
449 assert!(EnhancedPointerExtractor::is_valid_heap_pointer(0x1000));
451 assert!(!EnhancedPointerExtractor::is_valid_heap_pointer(0xFFF));
452
453 #[cfg(target_pointer_width = "64")]
455 {
456 assert!(!EnhancedPointerExtractor::is_valid_heap_pointer(
457 0x8000_0000_0000_0000
458 ));
459 assert!(EnhancedPointerExtractor::is_valid_heap_pointer(
460 0x7FFF_FFFF_FFFF_FFFF
461 ));
462 }
463
464 #[cfg(target_pointer_width = "32")]
465 {
466 assert!(!EnhancedPointerExtractor::is_valid_heap_pointer(
467 0x8000_0000
468 ));
469 assert!(EnhancedPointerExtractor::is_valid_heap_pointer(0x7FFF_FFFF));
470 }
471
472 assert!(!EnhancedPointerExtractor::is_valid_heap_pointer(usize::MAX));
474 }
475
476 #[test]
477 fn test_synthetic_pointer_ranges() {
478 assert!(EnhancedPointerExtractor::is_synthetic_pointer(0x5000_0000));
480 assert!(EnhancedPointerExtractor::is_synthetic_pointer(0x5FFF_FFFF));
481 assert!(!EnhancedPointerExtractor::is_synthetic_pointer(0x4FFF_FFFF));
482 assert!(!EnhancedPointerExtractor::is_synthetic_pointer(0x6000_0000));
483
484 assert!(EnhancedPointerExtractor::is_synthetic_pointer(0x8000_0000));
485 assert!(EnhancedPointerExtractor::is_synthetic_pointer(0x8FFF_FFFF));
486 assert!(!EnhancedPointerExtractor::is_synthetic_pointer(0x7FFF_FFFF));
487 assert!(EnhancedPointerExtractor::is_synthetic_pointer(0x9000_0000));
488
489 assert!(EnhancedPointerExtractor::is_synthetic_pointer(0xA000_0000));
490 assert!(EnhancedPointerExtractor::is_synthetic_pointer(0xFFFF_FFFF));
491 assert!(EnhancedPointerExtractor::is_synthetic_pointer(0x9FFF_FFFF));
492 }
493
494 #[test]
495 fn test_synthetic_reason_determination() {
496 assert_eq!(
498 EnhancedPointerExtractor::determine_synthetic_reason(0x5000_0000),
499 SyntheticReason::SmartPointerIndirection
500 );
501 assert_eq!(
502 EnhancedPointerExtractor::determine_synthetic_reason(0x5FFF_FFFF),
503 SyntheticReason::SmartPointerIndirection
504 );
505
506 assert_eq!(
507 EnhancedPointerExtractor::determine_synthetic_reason(0x8000_0000),
508 SyntheticReason::NoHeapAllocation
509 );
510 assert_eq!(
511 EnhancedPointerExtractor::determine_synthetic_reason(0x8FFF_FFFF),
512 SyntheticReason::NoHeapAllocation
513 );
514
515 assert_eq!(
516 EnhancedPointerExtractor::determine_synthetic_reason(0xA000_0000),
517 SyntheticReason::ComplexType
518 );
519 assert_eq!(
520 EnhancedPointerExtractor::determine_synthetic_reason(0xFFFF_FFFF),
521 SyntheticReason::ComplexType
522 );
523
524 assert_eq!(
526 EnhancedPointerExtractor::determine_synthetic_reason(0x1000),
527 SyntheticReason::InvalidPointer
528 );
529 }
530
531 #[test]
532 fn test_synthetic_pointer_generation() {
533 let ptr1 = EnhancedPointerExtractor::generate_synthetic_pointer();
535 let ptr2 = EnhancedPointerExtractor::generate_synthetic_pointer();
536 let ptr3 = EnhancedPointerExtractor::generate_synthetic_pointer();
537
538 assert_ne!(ptr1, ptr2);
539 assert_ne!(ptr2, ptr3);
540 assert_ne!(ptr1, ptr3);
541
542 assert!(ptr1 >= 0x9000_0000);
544 assert!(ptr2 >= 0x9000_0000);
545 assert!(ptr3 >= 0x9000_0000);
546
547 assert!(EnhancedPointerExtractor::is_synthetic_pointer(ptr1));
549 assert!(EnhancedPointerExtractor::is_synthetic_pointer(ptr2));
550 assert!(EnhancedPointerExtractor::is_synthetic_pointer(ptr3));
551 }
552
553 #[test]
554 fn test_string_pointer_extraction() {
555 let string = String::from("Hello, World!");
557 let pointer_info = EnhancedPointerExtractor::extract_string_pointer(&string);
558
559 match pointer_info {
560 PointerInfo::Real(_) => {
561 }
563 PointerInfo::Synthetic { reason, .. } => {
564 panic!("Expected real pointer for non-empty string, got synthetic: {reason:?}");
565 }
566 }
567
568 let empty_string = String::new();
570 let pointer_info = EnhancedPointerExtractor::extract_string_pointer(&empty_string);
571
572 match pointer_info {
573 PointerInfo::Synthetic {
574 reason: SyntheticReason::EmptyContainer,
575 ..
576 } => {
577 }
579 _ => {
580 panic!("Expected synthetic pointer with EmptyContainer reason for empty string");
581 }
582 }
583
584 let mut string_with_capacity = String::new();
586 string_with_capacity.reserve(100);
587 let pointer_info = EnhancedPointerExtractor::extract_string_pointer(&string_with_capacity);
588
589 match pointer_info {
590 PointerInfo::Real(_) => {
591 }
593 _ => {
594 panic!("Expected real pointer for string with capacity");
595 }
596 }
597 }
598
599 #[test]
600 fn test_box_pointer_extraction() {
601 let boxed_value = Box::new(42);
602 let pointer_info = EnhancedPointerExtractor::extract_box_pointer(&boxed_value);
603
604 match pointer_info {
605 PointerInfo::Real(_) => {
606 }
608 PointerInfo::Synthetic { reason, .. } => {
609 panic!("Expected real pointer for Box, got synthetic: {reason:?}");
610 }
611 }
612
613 let large_boxed = Box::new([0u8; 1024]);
615 let pointer_info = EnhancedPointerExtractor::extract_box_pointer(&large_boxed);
616
617 match pointer_info {
618 PointerInfo::Real(_) => {
619 }
621 _ => {
622 panic!("Expected real pointer for large Box");
623 }
624 }
625 }
626
627 #[test]
628 fn test_hashmap_pointer_extraction() {
629 use std::collections::HashMap;
630
631 let empty_map: HashMap<String, i32> = HashMap::new();
633 let pointer_info = EnhancedPointerExtractor::extract_hashmap_pointer(&empty_map);
634
635 match pointer_info {
636 PointerInfo::Synthetic {
637 reason: SyntheticReason::EmptyContainer,
638 ..
639 } => {
640 }
642 _ => {
643 panic!("Expected synthetic pointer with EmptyContainer reason for empty HashMap");
644 }
645 }
646
647 let mut map = HashMap::new();
649 map.insert("key1".to_string(), 1);
650 map.insert("key2".to_string(), 2);
651 let pointer_info = EnhancedPointerExtractor::extract_hashmap_pointer(&map);
652
653 match pointer_info {
654 PointerInfo::Synthetic {
655 reason: SyntheticReason::ComplexType,
656 ..
657 } => {
658 }
660 _ => {
661 panic!("Expected synthetic pointer with ComplexType reason for non-empty HashMap");
662 }
663 }
664 }
665
666 #[test]
667 fn test_enhanced_trackable_string() {
668 let string = String::from("Test string");
669 let pointer_info = string.get_pointer_info();
670 let size_estimate = EnhancedTrackable::get_size_estimate(&string);
671 let type_info = string.get_type_info();
672
673 match pointer_info {
674 PointerInfo::Real(_) => {
675 }
677 _ => panic!("Expected real pointer for non-empty string"),
678 }
679
680 assert!(size_estimate > 0);
681 assert_eq!(type_info.type_name, "String");
682 assert_eq!(type_info.category, TypeCategory::Collection);
683 assert_eq!(type_info.complexity_score, 1);
684 assert!(type_info.is_heap_allocated);
685
686 let empty_string = String::new();
688 let type_info = empty_string.get_type_info();
689 assert!(!type_info.is_heap_allocated);
690 }
691
692 #[test]
693 fn test_enhanced_trackable_box() {
694 let boxed_value = Box::new(42);
695 let pointer_info = boxed_value.get_pointer_info();
696 let size_estimate = EnhancedTrackable::get_size_estimate(&boxed_value);
697 let type_info = boxed_value.get_type_info();
698
699 match pointer_info {
700 PointerInfo::Real(_) => {
701 }
703 _ => panic!("Expected real pointer for Box"),
704 }
705
706 assert!(size_estimate > 0);
707 assert!(type_info.type_name.starts_with("Box<"));
708 assert_eq!(type_info.category, TypeCategory::SmartPointer);
709 assert_eq!(type_info.complexity_score, 2);
710 assert!(type_info.is_heap_allocated);
711 }
712
713 #[test]
714 fn test_pointer_statistics_edge_cases() {
715 let empty_pointers: Vec<PointerInfo> = vec![];
717 let stats = EnhancedPointerExtractor::get_pointer_statistics(&empty_pointers);
718
719 assert_eq!(stats.total_pointers, 0);
720 assert_eq!(stats.real_pointers, 0);
721 assert_eq!(stats.synthetic_pointers, 0);
722 assert_eq!(stats.real_pointer_ratio, 0.0);
723 assert!(stats.synthetic_reasons.is_empty());
724
725 let all_real = vec![
727 PointerInfo::Real(0x1000),
728 PointerInfo::Real(0x2000),
729 PointerInfo::Real(0x3000),
730 ];
731 let stats = EnhancedPointerExtractor::get_pointer_statistics(&all_real);
732
733 assert_eq!(stats.total_pointers, 3);
734 assert_eq!(stats.real_pointers, 3);
735 assert_eq!(stats.synthetic_pointers, 0);
736 assert_eq!(stats.real_pointer_ratio, 1.0);
737 assert!(stats.synthetic_reasons.is_empty());
738
739 let all_synthetic = vec![
741 PointerInfo::Synthetic {
742 ptr: 0x8000_0000,
743 reason: SyntheticReason::EmptyContainer,
744 },
745 PointerInfo::Synthetic {
746 ptr: 0x9000_0000,
747 reason: SyntheticReason::EmptyContainer,
748 },
749 PointerInfo::Synthetic {
750 ptr: 0xA000_0000,
751 reason: SyntheticReason::ComplexType,
752 },
753 ];
754 let stats = EnhancedPointerExtractor::get_pointer_statistics(&all_synthetic);
755
756 assert_eq!(stats.total_pointers, 3);
757 assert_eq!(stats.real_pointers, 0);
758 assert_eq!(stats.synthetic_pointers, 3);
759 assert_eq!(stats.real_pointer_ratio, 0.0);
760 assert_eq!(stats.synthetic_reasons.len(), 2);
761 assert_eq!(stats.synthetic_reasons[&SyntheticReason::EmptyContainer], 2);
762 assert_eq!(stats.synthetic_reasons[&SyntheticReason::ComplexType], 1);
763 }
764
765 #[test]
766 fn test_synthetic_reason_variants() {
767 let reasons = vec![
769 SyntheticReason::NoHeapAllocation,
770 SyntheticReason::EmptyContainer,
771 SyntheticReason::SmartPointerIndirection,
772 SyntheticReason::ComplexType,
773 SyntheticReason::InvalidPointer,
774 ];
775
776 for reason in &reasons {
778 let cloned = reason.clone();
779 assert_eq!(reason, &cloned);
780
781 let mut map = std::collections::HashMap::new();
783 map.insert(reason.clone(), 1);
784 assert_eq!(map.get(reason), Some(&1));
785 }
786 }
787
788 #[test]
789 fn test_type_category_variants() {
790 let categories = vec![
792 TypeCategory::Primitive,
793 TypeCategory::Collection,
794 TypeCategory::SmartPointer,
795 TypeCategory::Complex,
796 TypeCategory::Atomic,
797 TypeCategory::Synchronization,
798 TypeCategory::Custom,
799 ];
800
801 for category in &categories {
802 let cloned = category.clone();
803 assert_eq!(category, &cloned);
804 }
805 }
806
807 #[test]
808 fn test_pointer_info_serialization() {
809 let real_pointer = PointerInfo::Real(0x1000);
811 let synthetic_pointer = PointerInfo::Synthetic {
812 ptr: 0x8000_0000,
813 reason: SyntheticReason::EmptyContainer,
814 };
815
816 let _real_json =
818 serde_json::to_string(&real_pointer).expect("Failed to serialize real pointer");
819 let _synthetic_json = serde_json::to_string(&synthetic_pointer)
820 .expect("Failed to serialize synthetic pointer");
821 }
822
823 #[test]
824 fn test_concurrent_pointer_operations() {
825 let handles: Vec<_> = (0..10)
827 .map(|_| {
828 thread::spawn(|| {
829 let ptr1 = EnhancedPointerExtractor::generate_synthetic_pointer();
831 let ptr2 = EnhancedPointerExtractor::generate_synthetic_pointer();
832
833 assert!(EnhancedPointerExtractor::is_synthetic_pointer(ptr1));
835 assert!(EnhancedPointerExtractor::is_synthetic_pointer(ptr2));
836 assert_ne!(ptr1, ptr2);
837
838 assert!(EnhancedPointerExtractor::is_valid_heap_pointer(0x1000));
840 assert!(!EnhancedPointerExtractor::is_valid_heap_pointer(0));
841 assert!(EnhancedPointerExtractor::is_synthetic_pointer(0x8000_0000));
842
843 (ptr1, ptr2)
844 })
845 })
846 .collect();
847
848 let mut all_pointers = Vec::new();
849 for handle in handles {
850 let (ptr1, ptr2) = handle.join().expect("Thread panicked");
851 all_pointers.push(ptr1);
852 all_pointers.push(ptr2);
853 }
854
855 all_pointers.sort();
857 all_pointers.dedup();
858 assert_eq!(all_pointers.len(), 20); }
860
861 #[test]
862 fn test_vec_with_reserved_capacity() {
863 let vec: Vec<i32> = Vec::with_capacity(100);
865
866 let pointer_info = EnhancedPointerExtractor::extract_vec_pointer(&vec);
867 match pointer_info {
868 PointerInfo::Real(_) => {
869 }
871 _ => panic!("Expected real pointer for Vec with reserved capacity"),
872 }
873
874 let type_info = vec.get_type_info();
875 assert!(type_info.is_heap_allocated);
876 }
877
878 #[test]
879 fn test_large_data_structures() {
880 let large_vec: Vec<u8> = vec![0; 10000];
882 let pointer_info = large_vec.get_pointer_info();
883 let size_estimate = EnhancedTrackable::get_size_estimate(&large_vec);
884
885 match pointer_info {
886 PointerInfo::Real(_) => {
887 }
889 _ => panic!("Expected real pointer for large Vec"),
890 }
891
892 assert!(size_estimate >= 10000);
893
894 let large_string = "x".repeat(10000);
896 let pointer_info = large_string.get_pointer_info();
897 let size_estimate = EnhancedTrackable::get_size_estimate(&large_string);
898
899 match pointer_info {
900 PointerInfo::Real(_) => {
901 }
903 _ => panic!("Expected real pointer for large String"),
904 }
905
906 assert!(size_estimate >= 10000);
907 }
908}