Skip to main content

libsurfer/
transaction_container.rs

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 // for now
165    }
166
167    #[must_use]
168    pub fn is_fully_loaded(&self) -> bool {
169        true // for now
170    }
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/// If `gen_id` is `Some` this `TransactionStreamRef` is a generator, otherwise it's a stream
202#[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}