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