ddex_builder/linker/
reference_generator.rs1use super::types::{EntityType, ReferenceStyle};
4use indexmap::IndexMap;
5
6#[derive(Debug, Clone)]
8pub struct ReferenceGenerator {
9 style: ReferenceStyle,
11
12 counters: IndexMap<EntityType, u32>,
14
15 prefixes: IndexMap<EntityType, String>,
17}
18
19impl ReferenceGenerator {
20 pub fn new(style: ReferenceStyle) -> Self {
22 let mut prefixes = IndexMap::new();
23
24 prefixes.insert(EntityType::Release, "R".to_string());
26 prefixes.insert(EntityType::Resource, "A".to_string());
27 prefixes.insert(EntityType::Party, "P".to_string());
28 prefixes.insert(EntityType::Deal, "D".to_string());
29 prefixes.insert(EntityType::TechnicalDetails, "T".to_string());
30 prefixes.insert(EntityType::RightsController, "RC".to_string());
31
32 Self {
33 style,
34 counters: IndexMap::new(),
35 prefixes,
36 }
37 }
38
39 pub fn generate(&mut self, entity_type: EntityType) -> String {
41 match self.style.clone() { ReferenceStyle::Sequential => self.generate_sequential(entity_type),
43 ReferenceStyle::Custom(formatter) => formatter(entity_type, self.next_counter(entity_type)),
44 ReferenceStyle::Prefixed { separator } => self.generate_prefixed(entity_type, &separator),
45 }
46 }
47
48 fn generate_sequential(&mut self, entity_type: EntityType) -> String {
50 let prefix = self.prefixes.get(&entity_type)
51 .expect("Unknown entity type")
52 .clone(); let counter = self.next_counter(entity_type);
54 format!("{}{}", prefix, counter)
55 }
56
57 fn generate_prefixed(&mut self, entity_type: EntityType, separator: &str) -> String {
59 let prefix = self.prefixes.get(&entity_type)
60 .expect("Unknown entity type")
61 .clone(); let counter = self.next_counter(entity_type);
63 format!("{}{}{}", prefix, separator, counter)
64 }
65
66 fn next_counter(&mut self, entity_type: EntityType) -> u32 {
68 let counter = self.counters.entry(entity_type).or_insert(0);
69 *counter += 1;
70 *counter
71 }
72
73 pub fn set_prefix(&mut self, entity_type: EntityType, prefix: String) {
75 self.prefixes.insert(entity_type, prefix);
76 }
77
78 pub fn reset_counter(&mut self, entity_type: EntityType) {
80 self.counters.insert(entity_type, 0);
81 }
82
83 pub fn reset_all_counters(&mut self) {
85 self.counters.clear();
86 }
87
88 pub fn get_counter(&self, entity_type: EntityType) -> u32 {
90 self.counters.get(&entity_type).copied().unwrap_or(0)
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn test_sequential_generation() {
100 let mut gen = ReferenceGenerator::new(ReferenceStyle::Sequential);
101
102 assert_eq!(gen.generate(EntityType::Resource), "A1");
103 assert_eq!(gen.generate(EntityType::Resource), "A2");
104 assert_eq!(gen.generate(EntityType::Release), "R1");
105 assert_eq!(gen.generate(EntityType::Resource), "A3");
106 assert_eq!(gen.generate(EntityType::Release), "R2");
107 }
108
109 #[test]
110 fn test_deterministic_ordering() {
111 let mut gen1 = ReferenceGenerator::new(ReferenceStyle::Sequential);
112 let mut gen2 = ReferenceGenerator::new(ReferenceStyle::Sequential);
113
114 for _ in 0..5 {
116 assert_eq!(
117 gen1.generate(EntityType::Resource),
118 gen2.generate(EntityType::Resource)
119 );
120 }
121 }
122}