ddex_builder/linker/
mod.rs1mod 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; #[derive(Debug, Clone)]
21pub struct ReferenceLinker {
22    generator: ReferenceGenerator,
24
25    relationships: RelationshipManager,
27
28    auto_linker: AutoLinker,
30
31    #[allow(dead_code)]
33    config: LinkerConfig,
34}
35
36impl ReferenceLinker {
37    pub fn new() -> Self {
39        Self::with_config(LinkerConfig::default())
40    }
41
42    pub fn with_config(config: LinkerConfig) -> Self {
44        Self {
45            generator: ReferenceGenerator::new(config.reference_style.clone()),
46            relationships: RelationshipManager::new(),
47            auto_linker: AutoLinker::new(),
48            config: config,
49        }
50    }
51
52    pub fn generate_reference(&mut self, entity_type: EntityType) -> String {
54        self.generator.generate(entity_type)
55    }
56
57    pub fn register_entity(&mut self, entity_type: EntityType, id: String, reference: String) {
59        self.relationships.register(entity_type, id, reference);
60    }
61
62    pub fn link_release_to_resources(
64        &mut self,
65        release_id: &str,
66        resource_ids: &[String],
67    ) -> Result<Vec<ReleaseResourceReference>, LinkingError> {
68        let release_ref = self
70            .relationships
71            .get_reference(EntityType::Release, release_id)
72            .unwrap_or_else(|| {
73                let ref_val = self.generator.generate(EntityType::Release);
74                self.relationships.register(
75                    EntityType::Release,
76                    release_id.to_string(),
77                    ref_val.clone(),
78                );
79                ref_val
80            });
81
82        let mut references = Vec::new();
84        for (sequence_no, resource_id) in resource_ids.iter().enumerate() {
85            let resource_ref = self
86                .relationships
87                .get_reference(EntityType::Resource, resource_id)
88                .ok_or_else(|| LinkingError::UnknownResource(resource_id.clone()))?;
89
90            references.push(ReleaseResourceReference {
91                release_reference: release_ref.clone(),
92                resource_reference: resource_ref,
93                sequence_number: sequence_no as u32 + 1,
94            });
95        }
96
97        Ok(references)
98    }
99
100    pub fn auto_link_request(
102        &mut self,
103        request: &mut crate::builder::BuildRequest,
104    ) -> Result<LinkingReport, LinkingError> {
105        self.auto_linker
106            .process_request(request, &mut self.generator, &mut self.relationships)
107    }
108
109    pub fn get_all_references(&self) -> IndexMap<EntityType, IndexMap<String, String>> {
111        self.relationships.get_all()
112    }
113
114    pub fn validate_references(&self) -> Result<(), Vec<LinkingError>> {
116        self.relationships.validate()
117    }
118}
119
120impl Default for ReferenceLinker {
121    fn default() -> Self {
122        Self::new()
123    }
124}