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