Skip to main content

memscope_rs/capture/types/
ownership.rs

1//! Ownership tracking types.
2//!
3//! This module contains types for tracking ownership hierarchy,
4//! ownership transfers, weak references, and circular references.
5
6use serde::{Deserialize, Serialize};
7
8use super::generic::MemoryImpact;
9use super::leak_detection::LeakRiskLevel;
10
11/// Ownership hierarchy analysis.
12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13pub struct OwnershipHierarchy {
14    /// Root owners in the hierarchy.
15    pub root_owners: Vec<OwnershipNode>,
16    /// Maximum ownership depth.
17    pub max_depth: usize,
18    /// Total objects in hierarchy.
19    pub total_objects: usize,
20    /// Ownership transfer events.
21    pub transfer_events: Vec<OwnershipTransferEvent>,
22    /// Weak reference analysis.
23    pub weak_references: Vec<WeakReferenceInfo>,
24    /// Circular reference detection.
25    pub circular_references: Vec<CircularReferenceInfo>,
26}
27
28/// Node in ownership hierarchy.
29#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
30pub struct OwnershipNode {
31    /// Object identifier.
32    pub object_id: usize,
33    /// Object type name.
34    pub type_name: String,
35    /// Ownership type.
36    pub ownership_type: OwnershipType,
37    /// Owned objects.
38    pub owned_objects: Vec<OwnershipNode>,
39    /// Reference count (for Rc/Arc).
40    pub reference_count: Option<usize>,
41    /// Weak reference count.
42    pub weak_reference_count: Option<usize>,
43}
44
45/// Types of ownership.
46#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
47pub enum OwnershipType {
48    /// Unique ownership (Box, owned values).
49    Unique,
50    /// Shared ownership (Rc).
51    SharedSingleThreaded,
52    /// Shared ownership (Arc).
53    SharedMultiThreaded,
54    /// Borrowed reference.
55    Borrowed,
56    /// Weak reference.
57    Weak,
58    /// Raw pointer (unsafe).
59    Raw,
60}
61
62/// Ownership transfer event.
63#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
64pub struct OwnershipTransferEvent {
65    /// Source object.
66    pub source_object: usize,
67    /// Target object.
68    pub target_object: usize,
69    /// Transfer type.
70    pub transfer_type: OwnershipTransferType,
71    /// Transfer timestamp.
72    pub timestamp: u64,
73    /// Transfer mechanism.
74    pub mechanism: String,
75}
76
77/// Types of ownership transfers.
78#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
79pub enum OwnershipTransferType {
80    /// Move operation.
81    Move,
82    /// Clone operation.
83    Clone,
84    /// Reference creation.
85    Borrow,
86    /// Reference counting increment.
87    ReferenceIncrement,
88    /// Reference counting decrement.
89    ReferenceDecrement,
90}
91
92/// Weak reference information.
93#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
94pub struct WeakReferenceInfo {
95    /// Weak reference object ID.
96    pub weak_ref_id: usize,
97    /// Target object ID.
98    pub target_object_id: usize,
99    /// Weak reference type.
100    pub weak_ref_type: WeakReferenceType,
101    /// Is target still alive.
102    pub target_alive: bool,
103    /// Upgrade attempts.
104    pub upgrade_attempts: u32,
105    /// Successful upgrades.
106    pub successful_upgrades: u32,
107}
108
109/// Types of weak references.
110#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
111pub enum WeakReferenceType {
112    /// std::rc::Weak.
113    RcWeak,
114    /// std::sync::Weak.
115    ArcWeak,
116    /// Custom weak reference.
117    Custom,
118}
119
120/// Circular reference information.
121#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
122pub struct CircularReferenceInfo {
123    /// Objects involved in the cycle.
124    pub cycle_objects: Vec<usize>,
125    /// Cycle detection timestamp.
126    pub detection_timestamp: u64,
127    /// Cycle type.
128    pub cycle_type: CircularReferenceType,
129    /// Potential memory leak risk.
130    pub leak_risk: LeakRiskLevel,
131    /// Suggested resolution.
132    pub resolution_suggestion: String,
133}
134
135/// Types of circular references.
136#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
137pub enum CircularReferenceType {
138    /// Direct circular reference (A -> B -> A).
139    Direct,
140    /// Indirect circular reference (A -> B -> C -> A).
141    Indirect,
142    /// Self-referential (A -> A).
143    SelfReferential,
144    /// Complex multi-path cycle.
145    Complex,
146}
147
148/// Type relationship information.
149#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
150pub struct TypeRelationshipInfo {
151    /// Type name.
152    pub type_name: String,
153    /// Parent types (traits, base structs).
154    pub parent_types: Vec<ParentTypeInfo>,
155    /// Child types (implementors, derived types).
156    pub child_types: Vec<ChildTypeInfo>,
157    /// Composed types (fields, associated types).
158    pub composed_types: Vec<ComposedTypeInfo>,
159    /// Relationship complexity score.
160    pub complexity_score: u32,
161    /// Inheritance depth.
162    pub inheritance_depth: u32,
163    /// Composition breadth.
164    pub composition_breadth: u32,
165}
166
167/// Parent type information.
168#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
169pub struct ParentTypeInfo {
170    /// Parent type name.
171    pub type_name: String,
172    /// Relationship type.
173    pub relationship_type: RelationshipType,
174    /// Inheritance level.
175    pub inheritance_level: u32,
176    /// Memory layout impact.
177    pub memory_impact: MemoryImpact,
178}
179
180/// Child type information.
181#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
182pub struct ChildTypeInfo {
183    /// Child type name.
184    pub type_name: String,
185    /// Relationship type.
186    pub relationship_type: RelationshipType,
187    /// Specialization level.
188    pub specialization_level: u32,
189    /// Usage frequency.
190    pub usage_frequency: u32,
191}
192
193/// Composed type information.
194#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
195pub struct ComposedTypeInfo {
196    /// Composed type name.
197    pub type_name: String,
198    /// Field or association name.
199    pub field_name: String,
200    /// Composition type.
201    pub composition_type: CompositionType,
202    /// Memory offset (if applicable).
203    pub memory_offset: Option<usize>,
204    /// Access frequency.
205    pub access_frequency: u32,
206}
207
208/// Type relationship types.
209#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
210pub enum RelationshipType {
211    /// Trait implementation relationship.
212    TraitImplementation,
213    /// Trait bound relationship.
214    TraitBound,
215    /// Inheritance relationship.
216    Inheritance,
217    /// Association relationship.
218    Association,
219    /// Aggregation relationship.
220    Composition,
221    /// Dependency relationship.
222    Dependency,
223}
224
225/// Composition types.
226#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
227pub enum CompositionType {
228    /// Field composition type.
229    Field,
230    /// Associated type composition type.
231    AssociatedType,
232    /// Generic parameter composition type.
233    GenericParameter,
234    /// Nested type composition type.
235    NestedType,
236    /// Reference composition type.
237    Reference,
238    /// Smart pointer composition type.
239    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    /// Objective: Verify OwnershipNode creation with nested children
499    /// Invariants: Should handle nested ownership hierarchy
500    #[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    /// Objective: Verify OwnershipTransferEvent creation
533    /// Invariants: All fields should be accessible
534    #[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    /// Objective: Verify OwnershipTransferType variants
554    /// Invariants: All variants should be distinct
555    #[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    /// Objective: Verify CircularReferenceInfo creation
575    /// Invariants: All fields should be properly initialized
576    #[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    /// Objective: Verify CircularReferenceType variants
599    /// Invariants: All variants should be distinct
600    #[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    /// Objective: Verify TypeRelationshipInfo creation
623    /// Invariants: All fields should be accessible
624    #[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    /// Objective: Verify ParentTypeInfo creation
641    /// Invariants: All fields should be properly initialized
642    #[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    /// Objective: Verify RelationshipType variants
659    /// Invariants: All variants should be distinct
660    #[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    /// Objective: Verify CompositionType variants
681    /// Invariants: All variants should be distinct
682    #[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    /// Objective: Verify ComposedTypeInfo creation
703    /// Invariants: All fields should be accessible
704    #[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    /// Objective: Verify OwnershipHierarchy with multiple root owners
723    /// Invariants: Should handle multiple root owners
724    #[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    /// Objective: Verify serialization of OwnershipType
761    /// Invariants: Should serialize and deserialize correctly
762    #[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    /// Objective: Verify WeakReferenceType variants
778    /// Invariants: All variants should be distinct
779    #[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    /// Objective: Verify ChildTypeInfo creation
789    /// Invariants: All fields should be accessible
790    #[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}