ddex_parser/transform/
graph.rs1use crate::error::ParseError;
4use crate::parser::namespace_detector::NamespaceContext;
5use ddex_core::models::graph::{
6 ERNMessage, MessageHeader, MessageType, MessageSender, MessageRecipient,
7 Release
8};
9use ddex_core::models::versions::ERNVersion;
10use quick_xml::Reader;
11use quick_xml::events::Event;
12use std::io::BufRead;
13
14pub struct GraphBuilder {
15 version: ERNVersion,
16}
17
18impl GraphBuilder {
19 pub fn new(version: ERNVersion) -> Self {
20 Self { version }
21 }
22
23 pub fn build_from_xml<R: BufRead>(&self, reader: R) -> Result<ERNMessage, ParseError> {
24 let mut xml_reader = Reader::from_reader(reader);
25 xml_reader.config_mut().trim_text(true);
26
27 let message_header = self.parse_header(&mut xml_reader)?;
28 let mut releases = Vec::new();
29 let resources = Vec::new(); let parties = Vec::new(); let deals = Vec::new(); let mut buf = Vec::new();
35 let mut in_release_list = false;
36
37 loop {
38 match xml_reader.read_event_into(&mut buf) {
39 Ok(Event::Start(ref e)) => {
40 match e.name().as_ref() {
41 b"ReleaseList" => in_release_list = true,
42 b"Release" if in_release_list => {
43 releases.push(self.parse_minimal_release(&mut xml_reader)?);
45 }
46 _ => {}
47 }
48 }
49 Ok(Event::End(ref e)) => {
50 if e.name().as_ref() == b"ReleaseList" {
51 in_release_list = false;
52 }
53 }
54 Ok(Event::Eof) => break,
55 _ => {}
56 }
57 buf.clear();
58 }
59
60 Ok(ERNMessage {
61 message_header,
62 parties,
63 resources,
64 releases,
65 deals,
66 version: self.version,
67 profile: None,
68 message_audit_trail: None,
69 extensions: None,
70 legacy_extensions: None,
71 comments: None,
72 attributes: None,
73 })
74 }
75
76 pub fn build_from_xml_with_context<R: BufRead>(&self, reader: R, _context: NamespaceContext) -> Result<ERNMessage, ParseError> {
78 self.build_from_xml(reader)
81 }
82
83 fn parse_header<R: BufRead>(&self, _reader: &mut Reader<R>) -> Result<MessageHeader, ParseError> {
84 use chrono::Utc;
85
86 Ok(MessageHeader {
88 message_id: format!("MSG_{:?}", self.version),
89 message_type: MessageType::NewReleaseMessage,
90 message_created_date_time: Utc::now(),
91 message_sender: MessageSender {
92 party_id: Vec::new(),
93 party_name: Vec::new(),
94 trading_name: None,
95 extensions: None,
96 attributes: None,
97 comments: None,
98 },
99 message_recipient: MessageRecipient {
100 party_id: Vec::new(),
101 party_name: Vec::new(),
102 trading_name: None,
103 extensions: None,
104 attributes: None,
105 comments: None,
106 },
107 message_control_type: None,
108 message_thread_id: Some("THREAD_001".to_string()),
109 extensions: None,
110 attributes: None,
111 comments: None,
112 })
113 }
114
115 fn parse_minimal_release<R: BufRead>(&self, reader: &mut Reader<R>) -> Result<Release, ParseError> {
116 use ddex_core::models::common::LocalizedString;
117
118 let release = Release { release_reference: format!("R_{:?}", self.version),
120 release_id: Vec::new(),
121 release_title: vec![LocalizedString::new(format!("Test Release {:?}", self.version))],
122 release_subtitle: None,
123 release_type: None,
124 genre: Vec::new(),
125 release_resource_reference_list: Vec::new(),
126 display_artist: Vec::new(),
127 party_list: Vec::new(),
128 release_date: Vec::new(),
129 territory_code: Vec::new(),
130 excluded_territory_code: Vec::new(),
131 extensions: None,
132 attributes: None,
133 comments: None,
134 };
135
136 let mut buf = Vec::new();
138 let mut depth = 1;
139 while depth > 0 {
140 match reader.read_event_into(&mut buf) {
141 Ok(Event::Start(_)) => depth += 1,
142 Ok(Event::End(_)) => depth -= 1,
143 Ok(Event::Eof) => break,
144 _ => {}
145 }
146 buf.clear();
147 }
148
149 Ok(release)
150 }
151}