Skip to main content

libsurfer/
transaction_container.rs

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