ddex_builder/linker/
mod.rs

1//! Reference linker for automatic ID generation and relationship management
2//!
3//! The linker module ensures deterministic reference generation and maintains
4//! relationships between DDEX entities (releases, resources, parties, deals).
5
6mod auto_linker;
7mod reference_generator;
8mod relationship_manager;
9mod types;
10
11pub use auto_linker::AutoLinker;
12pub use reference_generator::ReferenceGenerator;
13pub use relationship_manager::RelationshipManager;
14pub use types::*;
15
16use indexmap::IndexMap;  // Removed IndexSet (unused)
17// Removed std::fmt (unused)
18
19/// Main reference linker that coordinates all linking operations
20#[derive(Debug, Clone)]
21pub struct ReferenceLinker {
22    /// Reference generator for creating deterministic IDs
23    generator: ReferenceGenerator,
24    
25    /// Relationship manager for tracking entity connections
26    relationships: RelationshipManager,
27    
28    /// Auto-linker for automatic relationship creation
29    auto_linker: AutoLinker,
30    
31    /// Configuration for the linker
32    config: LinkerConfig,
33}
34
35impl ReferenceLinker {
36    /// Create a new reference linker with default configuration
37    pub fn new() -> Self {
38        Self::with_config(LinkerConfig::default())
39    }
40    
41    /// Create a new reference linker with custom configuration
42    pub fn with_config(config: LinkerConfig) -> Self {
43        Self {
44            generator: ReferenceGenerator::new(config.reference_style.clone()),
45            relationships: RelationshipManager::new(),
46            auto_linker: AutoLinker::new(),
47            config,
48        }
49    }
50    
51    /// Generate a new reference for an entity type
52    pub fn generate_reference(&mut self, entity_type: EntityType) -> String {
53        self.generator.generate(entity_type)
54    }
55    
56    /// Register an entity with its reference
57    pub fn register_entity(&mut self, entity_type: EntityType, id: String, reference: String) {
58        self.relationships.register(entity_type, id, reference);
59    }
60    
61    /// Link a release to multiple resources
62    pub fn link_release_to_resources(
63        &mut self,
64        release_id: &str,
65        resource_ids: &[String],
66    ) -> Result<Vec<ReleaseResourceReference>, LinkerError> {
67        // Get or generate release reference
68        let release_ref = self.relationships
69            .get_reference(EntityType::Release, release_id)
70            .unwrap_or_else(|| {
71                let ref_val = self.generator.generate(EntityType::Release);
72                self.relationships.register(
73                    EntityType::Release, 
74                    release_id.to_string(), 
75                    ref_val.clone()
76                );
77                ref_val
78            });
79        
80        // Build release-resource references
81        let mut references = Vec::new();
82        for (sequence_no, resource_id) in resource_ids.iter().enumerate() {
83            let resource_ref = self.relationships
84                .get_reference(EntityType::Resource, resource_id)
85                .ok_or_else(|| LinkerError::UnknownResource(resource_id.clone()))?;
86            
87            references.push(ReleaseResourceReference {
88                release_reference: release_ref.clone(),
89                resource_reference: resource_ref,
90                sequence_number: sequence_no as u32 + 1,
91            });
92        }
93        
94        Ok(references)
95    }
96    
97    /// Auto-link all entities in a build request
98    pub fn auto_link_request(
99        &mut self,
100        request: &mut crate::builder::BuildRequest,
101    ) -> Result<LinkingReport, LinkerError> {
102        self.auto_linker.process_request(request, &mut self.generator, &mut self.relationships)
103    }
104    
105    /// Get all registered references for debugging
106    pub fn get_all_references(&self) -> IndexMap<EntityType, IndexMap<String, String>> {
107        self.relationships.get_all()
108    }
109    
110    /// Validate all references in the system
111    pub fn validate_references(&self) -> Result<(), Vec<LinkerError>> {
112        self.relationships.validate()
113    }
114}
115
116impl Default for ReferenceLinker {
117    fn default() -> Self {
118        Self::new()
119    }
120}