1use crate::time::{TimeScale, TimeUnit};
2use crate::wave_container::MetaData;
3use ftr_parser::types::{
4 FTR, GeneratorId, StreamId, Transaction, TransactionId, TxGenerator, TxStream,
5};
6use itertools::Itertools;
7use num::BigUint;
8use serde::{Deserialize, Serialize};
9use std::fmt::{Display, Formatter};
10use std::hash::{Hash, Hasher};
11use std::ops::Not;
12
13pub struct TransactionContainer {
14 pub inner: FTR,
15}
16
17impl TransactionContainer {
18 #[must_use]
19 pub fn get_streams(&self) -> Vec<&TxStream> {
20 self.inner.tx_streams.values().collect()
21 }
22
23 #[must_use]
24 pub fn get_stream(&self, stream_id: StreamId) -> Option<&TxStream> {
25 self.inner.get_stream(stream_id)
26 }
27
28 #[must_use]
29 pub fn get_stream_from_name(&self, name: String) -> Option<&TxStream> {
30 self.inner.get_stream_from_name(name)
31 }
32
33 #[must_use]
34 pub fn get_generators(&self) -> Vec<&TxGenerator> {
35 self.inner.tx_generators.values().collect()
36 }
37
38 #[must_use]
39 pub fn get_transaction(&self, transaction_ref: &TransactionRef) -> Option<&Transaction> {
40 self.inner.tx_generators.values().find_map(|g| {
41 g.transactions
42 .iter()
43 .find(|tx| tx.get_tx_id() == transaction_ref.id)
44 })
45 }
46
47 #[must_use]
48 pub fn get_generator(&self, gen_id: GeneratorId) -> Option<&TxGenerator> {
49 self.inner.get_generator(gen_id)
50 }
51 #[must_use]
52 pub fn get_generator_from_name(
53 &self,
54 stream_id: Option<StreamId>,
55 gen_name: String,
56 ) -> Option<&TxGenerator> {
57 self.inner.get_generator_from_name(stream_id, gen_name)
58 }
59
60 #[must_use]
61 pub fn get_transactions_from_generator(&self, gen_id: GeneratorId) -> Vec<TransactionId> {
62 self.get_generator(gen_id)
63 .unwrap()
64 .transactions
65 .iter()
66 .map(ftr_parser::types::Transaction::get_tx_id)
67 .collect_vec()
68 }
69
70 #[must_use]
71 pub fn get_transactions_from_stream(&self, stream_id: StreamId) -> Vec<TransactionId> {
72 self.get_stream(stream_id)
73 .unwrap()
74 .generators
75 .iter()
76 .flat_map(|g| {
77 self.get_generator(*g)
78 .unwrap()
79 .transactions
80 .iter()
81 .map(ftr_parser::types::Transaction::get_tx_id)
82 .collect_vec()
83 })
84 .collect()
85 }
86 #[must_use]
87 pub fn stream_scope_exists(&self, stream_scope: &StreamScopeRef) -> bool {
88 match stream_scope {
89 StreamScopeRef::Root => true,
90 StreamScopeRef::Stream(s) => self.inner.tx_streams.contains_key(&s.stream_id),
91 StreamScopeRef::Empty(_) => false,
92 }
93 }
94
95 #[must_use]
96 pub fn stream_names(&self) -> Vec<String> {
97 let mut names = vec![String::from("tr")];
98 let mut stream_names: Vec<String> = self
99 .get_streams()
100 .into_iter()
101 .map(|s| s.name.clone())
102 .collect();
103 names.append(&mut stream_names);
104
105 names
106 }
107
108 #[must_use]
109 pub fn generator_names(&self) -> Vec<String> {
110 self.get_generators()
111 .into_iter()
112 .map(|g| g.name.clone())
113 .collect()
114 }
115
116 #[must_use]
117 pub fn generators_in_stream(&self, stream_scope: &StreamScopeRef) -> Vec<TransactionStreamRef> {
118 match stream_scope {
119 StreamScopeRef::Root => self
120 .get_streams()
121 .into_iter()
122 .map(|s| TransactionStreamRef {
123 gen_id: None,
124 stream_id: s.id,
125 name: s.name.clone(),
126 })
127 .collect(),
128 StreamScopeRef::Stream(stream_ref) => self
129 .get_stream(stream_ref.stream_id)
130 .unwrap()
131 .generators
132 .iter()
133 .map(|id| {
134 let generator = self.get_generator(*id).unwrap();
135 TransactionStreamRef {
136 gen_id: Some(generator.id),
137 stream_id: stream_ref.stream_id,
138 name: generator.name.clone(),
139 }
140 })
141 .collect(),
142 StreamScopeRef::Empty(_) => vec![],
143 }
144 }
145
146 #[must_use]
147 pub fn max_timestamp(&self) -> Option<BigUint> {
148 Some(BigUint::try_from(&self.inner.max_timestamp).unwrap())
149 }
150
151 #[must_use]
152 pub fn metadata(&self) -> MetaData {
153 MetaData {
154 date: None,
155 version: None,
156 timescale: TimeScale {
157 unit: TimeUnit::from(self.inner.time_scale),
158 multiplier: None,
159 },
160 }
161 }
162
163 #[must_use]
164 pub fn body_loaded(&self) -> bool {
165 true }
167
168 #[must_use]
169 pub fn is_fully_loaded(&self) -> bool {
170 true }
172}
173
174#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
175pub enum StreamScopeRef {
176 Root,
177 Stream(TransactionStreamRef),
178 Empty(String),
179}
180
181impl Display for StreamScopeRef {
182 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
183 match self {
184 StreamScopeRef::Root => write!(f, "Root scope"),
185 StreamScopeRef::Stream(s) => s.fmt(f),
186 StreamScopeRef::Empty(_) => write!(f, "Empty stream scope"),
187 }
188 }
189}
190
191impl StreamScopeRef {
192 #[must_use]
193 pub fn new_stream_from_name(transactions: &TransactionContainer, name: String) -> Self {
194 let stream = transactions
195 .inner
196 .get_stream_from_name(name.clone())
197 .unwrap();
198 StreamScopeRef::Stream(TransactionStreamRef::new_stream(stream.id, name))
199 }
200}
201
202#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
204pub struct TransactionStreamRef {
205 pub stream_id: StreamId,
206 pub gen_id: Option<GeneratorId>,
207 pub name: String,
208}
209
210impl Hash for TransactionStreamRef {
211 fn hash<H: Hasher>(&self, state: &mut H) {
212 self.gen_id
213 .unwrap_or(GeneratorId(self.stream_id.0))
214 .hash(state);
215 self.name.hash(state);
216 }
217}
218
219impl Display for TransactionStreamRef {
220 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
221 if self.is_generator() {
222 write!(
223 f,
224 "Generator: id: {}, stream_id: {}, name: {}",
225 self.gen_id.unwrap(),
226 self.stream_id,
227 self.name
228 )
229 } else {
230 write!(f, "Stream: id: {}, name: {}", self.stream_id, self.name)
231 }
232 }
233}
234
235impl TransactionStreamRef {
236 #[must_use]
237 pub fn new_stream(stream_id: StreamId, name: String) -> Self {
238 TransactionStreamRef {
239 stream_id,
240 gen_id: None,
241 name,
242 }
243 }
244 #[must_use]
245 pub fn new_gen(stream_id: StreamId, gen_id: GeneratorId, name: String) -> Self {
246 TransactionStreamRef {
247 stream_id,
248 gen_id: Some(gen_id),
249 name,
250 }
251 }
252
253 #[must_use]
254 pub fn is_generator(&self) -> bool {
255 self.gen_id.is_some()
256 }
257
258 #[must_use]
259 pub fn is_stream(&self) -> bool {
260 self.is_generator().not()
261 }
262}
263
264#[derive(Clone, Debug, Eq, Hash, Serialize, Deserialize, PartialEq)]
265pub struct TransactionRef {
266 pub id: TransactionId,
267}