1use serde::{Deserialize, Serialize};
7
8use super::generic::MemoryImpact;
9use super::leak_detection::LeakRiskLevel;
10
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13pub struct OwnershipHierarchy {
14 pub root_owners: Vec<OwnershipNode>,
16 pub max_depth: usize,
18 pub total_objects: usize,
20 pub transfer_events: Vec<OwnershipTransferEvent>,
22 pub weak_references: Vec<WeakReferenceInfo>,
24 pub circular_references: Vec<CircularReferenceInfo>,
26}
27
28#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
30pub struct OwnershipNode {
31 pub object_id: usize,
33 pub type_name: String,
35 pub ownership_type: OwnershipType,
37 pub owned_objects: Vec<OwnershipNode>,
39 pub reference_count: Option<usize>,
41 pub weak_reference_count: Option<usize>,
43}
44
45#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
47pub enum OwnershipType {
48 Unique,
50 SharedSingleThreaded,
52 SharedMultiThreaded,
54 Borrowed,
56 Weak,
58 Raw,
60}
61
62#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
64pub struct OwnershipTransferEvent {
65 pub source_object: usize,
67 pub target_object: usize,
69 pub transfer_type: OwnershipTransferType,
71 pub timestamp: u64,
73 pub mechanism: String,
75}
76
77#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
79pub enum OwnershipTransferType {
80 Move,
82 Clone,
84 Borrow,
86 ReferenceIncrement,
88 ReferenceDecrement,
90}
91
92#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
94pub struct WeakReferenceInfo {
95 pub weak_ref_id: usize,
97 pub target_object_id: usize,
99 pub weak_ref_type: WeakReferenceType,
101 pub target_alive: bool,
103 pub upgrade_attempts: u32,
105 pub successful_upgrades: u32,
107}
108
109#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
111pub enum WeakReferenceType {
112 RcWeak,
114 ArcWeak,
116 Custom,
118}
119
120#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
122pub struct CircularReferenceInfo {
123 pub cycle_objects: Vec<usize>,
125 pub detection_timestamp: u64,
127 pub cycle_type: CircularReferenceType,
129 pub leak_risk: LeakRiskLevel,
131 pub resolution_suggestion: String,
133}
134
135#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
137pub enum CircularReferenceType {
138 Direct,
140 Indirect,
142 SelfReferential,
144 Complex,
146}
147
148#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
150pub struct TypeRelationshipInfo {
151 pub type_name: String,
153 pub parent_types: Vec<ParentTypeInfo>,
155 pub child_types: Vec<ChildTypeInfo>,
157 pub composed_types: Vec<ComposedTypeInfo>,
159 pub complexity_score: u32,
161 pub inheritance_depth: u32,
163 pub composition_breadth: u32,
165}
166
167#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
169pub struct ParentTypeInfo {
170 pub type_name: String,
172 pub relationship_type: RelationshipType,
174 pub inheritance_level: u32,
176 pub memory_impact: MemoryImpact,
178}
179
180#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
182pub struct ChildTypeInfo {
183 pub type_name: String,
185 pub relationship_type: RelationshipType,
187 pub specialization_level: u32,
189 pub usage_frequency: u32,
191}
192
193#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
195pub struct ComposedTypeInfo {
196 pub type_name: String,
198 pub field_name: String,
200 pub composition_type: CompositionType,
202 pub memory_offset: Option<usize>,
204 pub access_frequency: u32,
206}
207
208#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
210pub enum RelationshipType {
211 TraitImplementation,
213 TraitBound,
215 Inheritance,
217 Association,
219 Composition,
221 Dependency,
223}
224
225#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
227pub enum CompositionType {
228 Field,
230 AssociatedType,
232 GenericParameter,
234 NestedType,
236 Reference,
238 SmartPointer,
240}
241
242impl From<crate::core::types::TypeRelationshipInfo> for TypeRelationshipInfo {
243 fn from(old: crate::core::types::TypeRelationshipInfo) -> Self {
244 Self {
245 type_name: old.type_name,
246 parent_types: old
247 .parent_types
248 .into_iter()
249 .map(|p| ParentTypeInfo {
250 type_name: p.type_name,
251 relationship_type: match p.relationship_type {
252 crate::core::types::RelationshipType::TraitImplementation => {
253 RelationshipType::TraitImplementation
254 }
255 crate::core::types::RelationshipType::TraitBound => {
256 RelationshipType::TraitBound
257 }
258 crate::core::types::RelationshipType::Inheritance => {
259 RelationshipType::Inheritance
260 }
261 crate::core::types::RelationshipType::Association => {
262 RelationshipType::Association
263 }
264 crate::core::types::RelationshipType::Composition => {
265 RelationshipType::Composition
266 }
267 crate::core::types::RelationshipType::Dependency => {
268 RelationshipType::Dependency
269 }
270 },
271 inheritance_level: p.inheritance_level,
272 memory_impact: match p.memory_impact {
273 crate::core::types::MemoryImpact::None => MemoryImpact::None,
274 crate::core::types::MemoryImpact::SizeIncrease(s) => {
275 MemoryImpact::SizeIncrease(s)
276 }
277 crate::core::types::MemoryImpact::AlignmentChange(s) => {
278 MemoryImpact::AlignmentChange(s)
279 }
280 crate::core::types::MemoryImpact::LayoutChange(s) => {
281 MemoryImpact::LayoutChange(s)
282 }
283 },
284 })
285 .collect(),
286 child_types: old
287 .child_types
288 .into_iter()
289 .map(|c| ChildTypeInfo {
290 type_name: c.type_name,
291 relationship_type: match c.relationship_type {
292 crate::core::types::RelationshipType::TraitImplementation => {
293 RelationshipType::TraitImplementation
294 }
295 crate::core::types::RelationshipType::TraitBound => {
296 RelationshipType::TraitBound
297 }
298 crate::core::types::RelationshipType::Inheritance => {
299 RelationshipType::Inheritance
300 }
301 crate::core::types::RelationshipType::Association => {
302 RelationshipType::Association
303 }
304 crate::core::types::RelationshipType::Composition => {
305 RelationshipType::Composition
306 }
307 crate::core::types::RelationshipType::Dependency => {
308 RelationshipType::Dependency
309 }
310 },
311 specialization_level: c.specialization_level,
312 usage_frequency: c.usage_frequency,
313 })
314 .collect(),
315 composed_types: old
316 .composed_types
317 .into_iter()
318 .map(|c| ComposedTypeInfo {
319 type_name: c.type_name,
320 field_name: c.field_name,
321 composition_type: match c.composition_type {
322 crate::core::types::CompositionType::Field => CompositionType::Field,
323 crate::core::types::CompositionType::AssociatedType => {
324 CompositionType::AssociatedType
325 }
326 crate::core::types::CompositionType::GenericParameter => {
327 CompositionType::GenericParameter
328 }
329 crate::core::types::CompositionType::NestedType => {
330 CompositionType::NestedType
331 }
332 crate::core::types::CompositionType::Reference => {
333 CompositionType::Reference
334 }
335 crate::core::types::CompositionType::SmartPointer => {
336 CompositionType::SmartPointer
337 }
338 },
339 memory_offset: c.memory_offset,
340 access_frequency: c.access_frequency,
341 })
342 .collect(),
343 complexity_score: old.complexity_score,
344 inheritance_depth: old.inheritance_depth,
345 composition_breadth: old.composition_breadth,
346 }
347 }
348}
349
350impl From<crate::core::types::OwnershipNode> for OwnershipNode {
351 fn from(old: crate::core::types::OwnershipNode) -> Self {
352 Self {
353 object_id: old.object_id,
354 type_name: old.type_name,
355 ownership_type: match old.ownership_type {
356 crate::core::types::OwnershipType::Unique => OwnershipType::Unique,
357 crate::core::types::OwnershipType::SharedSingleThreaded => {
358 OwnershipType::SharedSingleThreaded
359 }
360 crate::core::types::OwnershipType::SharedMultiThreaded => {
361 OwnershipType::SharedMultiThreaded
362 }
363 crate::core::types::OwnershipType::Borrowed => OwnershipType::Borrowed,
364 crate::core::types::OwnershipType::Weak => OwnershipType::Weak,
365 crate::core::types::OwnershipType::Raw => OwnershipType::Raw,
366 },
367 owned_objects: old.owned_objects.into_iter().map(Into::into).collect(),
368 reference_count: old.reference_count,
369 weak_reference_count: old.weak_reference_count,
370 }
371 }
372}
373
374impl From<crate::core::types::OwnershipTransferEvent> for OwnershipTransferEvent {
375 fn from(old: crate::core::types::OwnershipTransferEvent) -> Self {
376 Self {
377 source_object: old.source_object,
378 target_object: old.target_object,
379 transfer_type: match old.transfer_type {
380 crate::core::types::OwnershipTransferType::Move => OwnershipTransferType::Move,
381 crate::core::types::OwnershipTransferType::Clone => OwnershipTransferType::Clone,
382 crate::core::types::OwnershipTransferType::Borrow => OwnershipTransferType::Borrow,
383 crate::core::types::OwnershipTransferType::ReferenceIncrement => {
384 OwnershipTransferType::ReferenceIncrement
385 }
386 crate::core::types::OwnershipTransferType::ReferenceDecrement => {
387 OwnershipTransferType::ReferenceDecrement
388 }
389 },
390 timestamp: old.timestamp,
391 mechanism: old.mechanism,
392 }
393 }
394}
395
396impl From<crate::core::types::WeakReferenceInfo> for WeakReferenceInfo {
397 fn from(old: crate::core::types::WeakReferenceInfo) -> Self {
398 Self {
399 weak_ref_id: old.weak_ref_id,
400 target_object_id: old.target_object_id,
401 weak_ref_type: match old.weak_ref_type {
402 crate::core::types::WeakReferenceType::RcWeak => WeakReferenceType::RcWeak,
403 crate::core::types::WeakReferenceType::ArcWeak => WeakReferenceType::ArcWeak,
404 crate::core::types::WeakReferenceType::Custom => WeakReferenceType::Custom,
405 },
406 target_alive: old.target_alive,
407 upgrade_attempts: old.upgrade_attempts,
408 successful_upgrades: old.successful_upgrades,
409 }
410 }
411}
412
413impl From<crate::core::types::CircularReferenceInfo> for CircularReferenceInfo {
414 fn from(old: crate::core::types::CircularReferenceInfo) -> Self {
415 Self {
416 cycle_objects: old.cycle_objects,
417 detection_timestamp: old.detection_timestamp,
418 cycle_type: match old.cycle_type {
419 crate::core::types::CircularReferenceType::Direct => CircularReferenceType::Direct,
420 crate::core::types::CircularReferenceType::Indirect => {
421 CircularReferenceType::Indirect
422 }
423 crate::core::types::CircularReferenceType::SelfReferential => {
424 CircularReferenceType::SelfReferential
425 }
426 crate::core::types::CircularReferenceType::Complex => {
427 CircularReferenceType::Complex
428 }
429 },
430 leak_risk: match old.leak_risk {
431 crate::core::types::LeakRiskLevel::Low => LeakRiskLevel::Low,
432 crate::core::types::LeakRiskLevel::Medium => LeakRiskLevel::Medium,
433 crate::core::types::LeakRiskLevel::High => LeakRiskLevel::High,
434 crate::core::types::LeakRiskLevel::Critical => LeakRiskLevel::Critical,
435 },
436 resolution_suggestion: old.resolution_suggestion,
437 }
438 }
439}
440
441impl From<crate::core::types::OwnershipHierarchy> for OwnershipHierarchy {
442 fn from(old: crate::core::types::OwnershipHierarchy) -> Self {
443 Self {
444 root_owners: old.root_owners.into_iter().map(Into::into).collect(),
445 max_depth: old.max_depth,
446 total_objects: old.total_objects,
447 transfer_events: old.transfer_events.into_iter().map(Into::into).collect(),
448 weak_references: old.weak_references.into_iter().map(Into::into).collect(),
449 circular_references: old
450 .circular_references
451 .into_iter()
452 .map(Into::into)
453 .collect(),
454 }
455 }
456}
457
458#[cfg(test)]
459mod tests {
460 use super::*;
461
462 #[test]
463 fn test_ownership_hierarchy() {
464 let hierarchy = OwnershipHierarchy {
465 root_owners: vec![],
466 max_depth: 3,
467 total_objects: 10,
468 transfer_events: vec![],
469 weak_references: vec![],
470 circular_references: vec![],
471 };
472
473 assert_eq!(hierarchy.max_depth, 3);
474 assert_eq!(hierarchy.total_objects, 10);
475 }
476
477 #[test]
478 fn test_ownership_type() {
479 let ownership = OwnershipType::SharedMultiThreaded;
480 assert!(matches!(ownership, OwnershipType::SharedMultiThreaded));
481 }
482
483 #[test]
484 fn test_weak_reference_info() {
485 let weak_ref = WeakReferenceInfo {
486 weak_ref_id: 1,
487 target_object_id: 100,
488 weak_ref_type: WeakReferenceType::ArcWeak,
489 target_alive: true,
490 upgrade_attempts: 5,
491 successful_upgrades: 4,
492 };
493
494 assert_eq!(weak_ref.upgrade_attempts, 5);
495 assert!(weak_ref.target_alive);
496 }
497
498 #[test]
501 fn test_ownership_node_nested() {
502 let child = OwnershipNode {
503 object_id: 2,
504 type_name: "Child".to_string(),
505 ownership_type: OwnershipType::Unique,
506 owned_objects: vec![],
507 reference_count: None,
508 weak_reference_count: None,
509 };
510
511 let parent = OwnershipNode {
512 object_id: 1,
513 type_name: "Parent".to_string(),
514 ownership_type: OwnershipType::SharedMultiThreaded,
515 owned_objects: vec![child],
516 reference_count: Some(3),
517 weak_reference_count: Some(1),
518 };
519
520 assert_eq!(
521 parent.owned_objects.len(),
522 1,
523 "Parent should have one child"
524 );
525 assert_eq!(
526 parent.reference_count,
527 Some(3),
528 "Reference count should be 3"
529 );
530 }
531
532 #[test]
535 fn test_ownership_transfer_event() {
536 let event = OwnershipTransferEvent {
537 source_object: 1,
538 target_object: 2,
539 transfer_type: OwnershipTransferType::Move,
540 timestamp: 1000,
541 mechanism: "std::move".to_string(),
542 };
543
544 assert_eq!(event.source_object, 1, "Source should match");
545 assert_eq!(event.target_object, 2, "Target should match");
546 assert_eq!(
547 event.transfer_type,
548 OwnershipTransferType::Move,
549 "Transfer type should be Move"
550 );
551 }
552
553 #[test]
556 fn test_ownership_transfer_type_variants() {
557 let variants = vec![
558 OwnershipTransferType::Move,
559 OwnershipTransferType::Clone,
560 OwnershipTransferType::Borrow,
561 OwnershipTransferType::ReferenceIncrement,
562 OwnershipTransferType::ReferenceDecrement,
563 ];
564
565 for variant in &variants {
566 let debug_str = format!("{variant:?}");
567 assert!(
568 !debug_str.is_empty(),
569 "Variant should have debug representation"
570 );
571 }
572 }
573
574 #[test]
577 fn test_circular_reference_info() {
578 let circular = CircularReferenceInfo {
579 cycle_objects: vec![1, 2, 3],
580 detection_timestamp: 1000,
581 cycle_type: CircularReferenceType::Indirect,
582 leak_risk: LeakRiskLevel::High,
583 resolution_suggestion: "Use Weak references".to_string(),
584 };
585
586 assert_eq!(
587 circular.cycle_objects.len(),
588 3,
589 "Should have 3 objects in cycle"
590 );
591 assert_eq!(
592 circular.cycle_type,
593 CircularReferenceType::Indirect,
594 "Cycle type should be Indirect"
595 );
596 }
597
598 #[test]
601 fn test_circular_reference_type_variants() {
602 assert_eq!(CircularReferenceType::Direct, CircularReferenceType::Direct);
603 assert_eq!(
604 CircularReferenceType::Indirect,
605 CircularReferenceType::Indirect
606 );
607 assert_eq!(
608 CircularReferenceType::SelfReferential,
609 CircularReferenceType::SelfReferential
610 );
611 assert_eq!(
612 CircularReferenceType::Complex,
613 CircularReferenceType::Complex
614 );
615
616 assert_ne!(
617 CircularReferenceType::Direct,
618 CircularReferenceType::Indirect
619 );
620 }
621
622 #[test]
625 fn test_type_relationship_info() {
626 let info = TypeRelationshipInfo {
627 type_name: "MyStruct".to_string(),
628 parent_types: vec![],
629 child_types: vec![],
630 composed_types: vec![],
631 complexity_score: 10,
632 inheritance_depth: 2,
633 composition_breadth: 5,
634 };
635
636 assert_eq!(info.type_name, "MyStruct", "Type name should match");
637 assert_eq!(info.complexity_score, 10, "Complexity score should match");
638 }
639
640 #[test]
643 fn test_parent_type_info() {
644 let parent = ParentTypeInfo {
645 type_name: "ParentTrait".to_string(),
646 relationship_type: RelationshipType::TraitImplementation,
647 inheritance_level: 1,
648 memory_impact: MemoryImpact::None,
649 };
650
651 assert_eq!(
652 parent.type_name, "ParentTrait",
653 "Parent type name should match"
654 );
655 assert_eq!(parent.inheritance_level, 1, "Inheritance level should be 1");
656 }
657
658 #[test]
661 fn test_relationship_type_variants() {
662 let variants = vec![
663 RelationshipType::TraitImplementation,
664 RelationshipType::TraitBound,
665 RelationshipType::Inheritance,
666 RelationshipType::Association,
667 RelationshipType::Composition,
668 RelationshipType::Dependency,
669 ];
670
671 for variant in &variants {
672 let debug_str = format!("{variant:?}");
673 assert!(
674 !debug_str.is_empty(),
675 "Variant should have debug representation"
676 );
677 }
678 }
679
680 #[test]
683 fn test_composition_type_variants() {
684 let variants = vec![
685 CompositionType::Field,
686 CompositionType::AssociatedType,
687 CompositionType::GenericParameter,
688 CompositionType::NestedType,
689 CompositionType::Reference,
690 CompositionType::SmartPointer,
691 ];
692
693 for variant in &variants {
694 let debug_str = format!("{variant:?}");
695 assert!(
696 !debug_str.is_empty(),
697 "Variant should have debug representation"
698 );
699 }
700 }
701
702 #[test]
705 fn test_composed_type_info() {
706 let composed = ComposedTypeInfo {
707 type_name: "InnerType".to_string(),
708 field_name: "inner".to_string(),
709 composition_type: CompositionType::Field,
710 memory_offset: Some(16),
711 access_frequency: 100,
712 };
713
714 assert_eq!(composed.field_name, "inner", "Field name should match");
715 assert_eq!(
716 composed.memory_offset,
717 Some(16),
718 "Memory offset should be 16"
719 );
720 }
721
722 #[test]
725 fn test_ownership_hierarchy_multiple_roots() {
726 let root1 = OwnershipNode {
727 object_id: 1,
728 type_name: "Root1".to_string(),
729 ownership_type: OwnershipType::Unique,
730 owned_objects: vec![],
731 reference_count: None,
732 weak_reference_count: None,
733 };
734
735 let root2 = OwnershipNode {
736 object_id: 2,
737 type_name: "Root2".to_string(),
738 ownership_type: OwnershipType::SharedSingleThreaded,
739 owned_objects: vec![],
740 reference_count: Some(2),
741 weak_reference_count: None,
742 };
743
744 let hierarchy = OwnershipHierarchy {
745 root_owners: vec![root1, root2],
746 max_depth: 5,
747 total_objects: 10,
748 transfer_events: vec![],
749 weak_references: vec![],
750 circular_references: vec![],
751 };
752
753 assert_eq!(
754 hierarchy.root_owners.len(),
755 2,
756 "Should have two root owners"
757 );
758 }
759
760 #[test]
763 fn test_ownership_type_serialization() {
764 let ownership = OwnershipType::SharedMultiThreaded;
765 let json = serde_json::to_string(&ownership);
766 assert!(json.is_ok(), "Should serialize to JSON");
767
768 let deserialized: Result<OwnershipType, _> = serde_json::from_str(&json.unwrap());
769 assert!(deserialized.is_ok(), "Should deserialize from JSON");
770 assert_eq!(
771 deserialized.unwrap(),
772 OwnershipType::SharedMultiThreaded,
773 "Should preserve value"
774 );
775 }
776
777 #[test]
780 fn test_weak_reference_type_variants() {
781 assert_eq!(WeakReferenceType::RcWeak, WeakReferenceType::RcWeak);
782 assert_eq!(WeakReferenceType::ArcWeak, WeakReferenceType::ArcWeak);
783 assert_eq!(WeakReferenceType::Custom, WeakReferenceType::Custom);
784
785 assert_ne!(WeakReferenceType::RcWeak, WeakReferenceType::ArcWeak);
786 }
787
788 #[test]
791 fn test_child_type_info() {
792 let child = ChildTypeInfo {
793 type_name: "ChildStruct".to_string(),
794 relationship_type: RelationshipType::Association,
795 specialization_level: 2,
796 usage_frequency: 50,
797 };
798
799 assert_eq!(
800 child.type_name, "ChildStruct",
801 "Child type name should match"
802 );
803 assert_eq!(child.usage_frequency, 50, "Usage frequency should match");
804 }
805}