ddex_parser/transform/
resolve.rs1use ddex_core::models::graph::{Deal, ERNMessage, Party, Release, Resource};
5use std::collections::HashMap;
6
7pub struct ReferenceResolver {
8 party_map: HashMap<String, Party>,
9 resource_map: HashMap<String, Resource>,
10 release_map: HashMap<String, Release>,
11 deal_map: HashMap<String, Deal>,
12}
13
14impl Default for ReferenceResolver {
15 fn default() -> Self {
16 Self::new()
17 }
18}
19
20impl ReferenceResolver {
21 pub fn new() -> Self {
22 Self {
23 party_map: HashMap::new(),
24 resource_map: HashMap::new(),
25 release_map: HashMap::new(),
26 deal_map: HashMap::new(),
27 }
28 }
29
30 pub fn build_maps(&mut self, message: &ERNMessage) {
31 for party in &message.parties {
33 if let Some(id) = party.party_id.first() {
34 self.party_map.insert(id.value.clone(), party.clone());
35 }
36 }
37
38 for resource in &message.resources {
40 self.resource_map
41 .insert(resource.resource_reference.clone(), resource.clone());
42 }
43
44 for release in &message.releases {
46 self.release_map
47 .insert(release.release_reference.clone(), release.clone());
48 }
49
50 for (idx, deal) in message.deals.iter().enumerate() {
52 let key = deal
53 .deal_reference
54 .clone()
55 .unwrap_or_else(|| format!("deal_{}", idx));
56 self.deal_map.insert(key, deal.clone());
57 }
58 }
59
60 pub fn resolve_party_reference(&self, reference: &str) -> Option<&Party> {
61 self.party_map.get(reference)
62 }
63
64 pub fn resolve_resource_reference(&self, reference: &str) -> Option<&Resource> {
65 self.resource_map.get(reference)
66 }
67
68 pub fn resolve_release_reference(&self, reference: &str) -> Option<&Release> {
69 self.release_map.get(reference)
70 }
71
72 pub fn validate_references(&self, message: &ERNMessage) -> Vec<UnresolvedReference> {
73 let mut unresolved = Vec::new();
74
75 for release in &message.releases {
77 for rref in &release.release_resource_reference_list {
78 if !self.resource_map.contains_key(&rref.resource_reference) {
79 unresolved.push(UnresolvedReference {
80 reference_type: "Resource".to_string(),
81 reference_value: rref.resource_reference.clone(),
82 location: format!(
83 "Release/{}/ResourceReference",
84 release.release_reference
85 ),
86 });
87 }
88 }
89 }
90
91 for (idx, deal) in message.deals.iter().enumerate() {
93 for release_ref in &deal.deal_release_reference {
94 if !self.release_map.contains_key(release_ref as &str) {
95 unresolved.push(UnresolvedReference {
96 reference_type: "Release".to_string(),
97 reference_value: release_ref.clone(),
98 location: format!("Deal[{}]/ReleaseReference", idx),
99 });
100 }
101 }
102 }
103
104 unresolved
105 }
106}
107
108#[derive(Debug, Clone)]
109pub struct UnresolvedReference {
110 pub reference_type: String,
111 pub reference_value: String,
112 pub location: String,
113}