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