libsurfer/
transaction_container.rs

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 // for now
141    }
142
143    pub fn is_fully_loaded(&self) -> bool {
144        true // for now
145    }
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/// If `gen_id` is `Some` this `TransactionStreamRef` is a generator, otherwise it's a stream
176#[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}