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() {
42 ReferenceStyle::Sequential => self.generate_sequential(entity_type),
44 ReferenceStyle::Custom(formatter) => {
45 formatter(entity_type, self.next_counter(entity_type))
46 }
47 ReferenceStyle::Prefixed { separator } => {
48 self.generate_prefixed(entity_type, &separator)
49 }
50 }
51 }
52
53 fn generate_sequential(&mut self, entity_type: EntityType) -> String {
55 let prefix = self
56 .prefixes
57 .get(&entity_type)
58 .expect("Unknown entity type")
59 .clone(); let counter = self.next_counter(entity_type);
61 format!("{}{}", prefix, counter)
62 }
63
64 fn generate_prefixed(&mut self, entity_type: EntityType, separator: &str) -> String {
66 let prefix = self
67 .prefixes
68 .get(&entity_type)
69 .expect("Unknown entity type")
70 .clone(); let counter = self.next_counter(entity_type);
72 format!("{}{}{}", prefix, separator, counter)
73 }
74
75 fn next_counter(&mut self, entity_type: EntityType) -> u32 {
77 let counter = self.counters.entry(entity_type).or_insert(0);
78 *counter += 1;
79 *counter
80 }
81
82 pub fn set_prefix(&mut self, entity_type: EntityType, prefix: String) {
84 self.prefixes.insert(entity_type, prefix);
85 }
86
87 pub fn reset_counter(&mut self, entity_type: EntityType) {
89 self.counters.insert(entity_type, 0);
90 }
91
92 pub fn reset_all_counters(&mut self) {
94 self.counters.clear();
95 }
96
97 pub fn get_counter(&self, entity_type: EntityType) -> u32 {
99 self.counters.get(&entity_type).copied().unwrap_or(0)
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn test_sequential_generation() {
109 let mut gen = ReferenceGenerator::new(ReferenceStyle::Sequential);
110
111 assert_eq!(gen.generate(EntityType::Resource), "A1");
112 assert_eq!(gen.generate(EntityType::Resource), "A2");
113 assert_eq!(gen.generate(EntityType::Release), "R1");
114 assert_eq!(gen.generate(EntityType::Resource), "A3");
115 assert_eq!(gen.generate(EntityType::Release), "R2");
116 }
117
118 #[test]
119 fn test_deterministic_ordering() {
120 let mut gen1 = ReferenceGenerator::new(ReferenceStyle::Sequential);
121 let mut gen2 = ReferenceGenerator::new(ReferenceStyle::Sequential);
122
123 for _ in 0..5 {
125 assert_eq!(
126 gen1.generate(EntityType::Resource),
127 gen2.generate(EntityType::Resource)
128 );
129 }
130 }
131}