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 let timescale = self.inner.time_scale;
154 MetaData {
155 date: None,
156 version: None,
157 timescale: TimeScale {
158 unit: TimeUnit::from(timescale),
159 multiplier: None,
160 },
161 }
162 }
163
164 #[must_use]
165 pub fn body_loaded(&self) -> bool {
166 true }
168
169 #[must_use]
170 pub fn is_fully_loaded(&self) -> bool {
171 true }
173}
174
175#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
176pub enum StreamScopeRef {
177 Root,
178 Stream(TransactionStreamRef),
179 Empty(String),
180}
181
182impl Display for StreamScopeRef {
183 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
184 match self {
185 StreamScopeRef::Root => write!(f, "Root scope"),
186 StreamScopeRef::Stream(s) => s.fmt(f),
187 StreamScopeRef::Empty(_) => write!(f, "Empty stream scope"),
188 }
189 }
190}
191
192impl StreamScopeRef {
193 #[must_use]
194 pub fn new_stream_from_name(transactions: &TransactionContainer, name: String) -> Self {
195 let stream = transactions
196 .inner
197 .get_stream_from_name(name.clone())
198 .unwrap();
199 StreamScopeRef::Stream(TransactionStreamRef::new_stream(stream.id, name))
200 }
201}
202
203#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
205pub struct TransactionStreamRef {
206 pub stream_id: StreamId,
207 pub gen_id: Option<GeneratorId>,
208 pub name: String,
209}
210
211impl Hash for TransactionStreamRef {
212 fn hash<H: Hasher>(&self, state: &mut H) {
213 self.gen_id
214 .unwrap_or(GeneratorId(self.stream_id.0))
215 .hash(state);
216 self.name.hash(state);
217 }
218}
219
220impl Display for TransactionStreamRef {
221 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
222 if self.is_generator() {
223 write!(
224 f,
225 "Generator: id: {}, stream_id: {}, name: {}",
226 self.gen_id.unwrap(),
227 self.stream_id,
228 self.name
229 )
230 } else {
231 write!(f, "Stream: id: {}, name: {}", self.stream_id, self.name)
232 }
233 }
234}
235
236impl TransactionStreamRef {
237 #[must_use]
238 pub fn new_stream(stream_id: StreamId, name: String) -> Self {
239 TransactionStreamRef {
240 stream_id,
241 gen_id: None,
242 name,
243 }
244 }
245 #[must_use]
246 pub fn new_gen(stream_id: StreamId, gen_id: GeneratorId, name: String) -> Self {
247 TransactionStreamRef {
248 stream_id,
249 gen_id: Some(gen_id),
250 name,
251 }
252 }
253
254 #[must_use]
255 pub fn is_generator(&self) -> bool {
256 self.gen_id.is_some()
257 }
258
259 #[must_use]
260 pub fn is_stream(&self) -> bool {
261 self.is_generator().not()
262 }
263}
264
265#[derive(Clone, Debug, Eq, Hash, Serialize, Deserialize, PartialEq)]
266pub struct TransactionRef {
267 pub id: TransactionId,
268}