Skip to main content

libsurfer/
data_container.rs

1use crate::time::{TimeScale, TimeUnit};
2use crate::transaction_container::{StreamScopeRef, TransactionContainer, TransactionStreamRef};
3use crate::wave_container::{MetaData, SimulationStatus, VariableRef, WaveContainer};
4use crate::wave_data::ScopeType;
5use crate::wave_data::ScopeType::{StreamScope, WaveScope};
6use num::BigUint;
7
8#[allow(clippy::large_enum_variant)]
9pub enum DataContainer {
10    Waves(WaveContainer),
11    Transactions(TransactionContainer),
12    Empty,
13}
14
15#[derive(Debug, Clone)]
16pub enum VariableType {
17    Variable(VariableRef),
18    Generator(TransactionStreamRef),
19}
20
21impl VariableType {
22    #[must_use]
23    pub fn name(&self) -> String {
24        match self {
25            VariableType::Variable(v) => v.name.clone(),
26            VariableType::Generator(g) => g.name.clone(),
27        }
28    }
29
30    #[must_use]
31    pub fn name_with_index(&self) -> String {
32        match self {
33            VariableType::Variable(v) => {
34                if let Some(index) = v.index {
35                    format!("{}[{}]", v.name, index)
36                } else {
37                    v.name.clone()
38                }
39            }
40            VariableType::Generator(g) => g.name.clone(),
41        }
42    }
43}
44
45impl DataContainer {
46    #[must_use]
47    pub fn __new_empty() -> Self {
48        DataContainer::Empty
49    }
50
51    #[must_use]
52    pub fn as_waves(&self) -> Option<&WaveContainer> {
53        match self {
54            DataContainer::Waves(w) => Some(w),
55            DataContainer::Transactions(_) => None,
56            DataContainer::Empty => None,
57        }
58    }
59
60    pub fn as_waves_mut(&mut self) -> Option<&mut WaveContainer> {
61        match self {
62            DataContainer::Waves(w) => Some(w),
63            DataContainer::Transactions(_) => None,
64            DataContainer::Empty => None,
65        }
66    }
67
68    #[must_use]
69    pub fn as_transactions(&self) -> Option<&TransactionContainer> {
70        match self {
71            DataContainer::Waves(_) => None,
72            DataContainer::Transactions(t) => Some(t),
73            DataContainer::Empty => None,
74        }
75    }
76
77    pub fn as_transactions_mut(&mut self) -> Option<&mut TransactionContainer> {
78        match self {
79            DataContainer::Waves(_) => None,
80            DataContainer::Transactions(t) => Some(t),
81            DataContainer::Empty => None,
82        }
83    }
84
85    #[must_use]
86    pub fn is_waves(&self) -> bool {
87        match self {
88            DataContainer::Waves(_) => true,
89            DataContainer::Transactions(_) => false,
90            DataContainer::Empty => false,
91        }
92    }
93
94    #[must_use]
95    pub fn is_transactions(&self) -> bool {
96        match self {
97            DataContainer::Waves(_) => false,
98            DataContainer::Transactions(_) => true,
99            DataContainer::Empty => false,
100        }
101    }
102
103    #[must_use]
104    pub fn max_timestamp(&self) -> Option<BigUint> {
105        match self {
106            DataContainer::Waves(w) => w.max_timestamp(),
107            DataContainer::Transactions(t) => t.max_timestamp(),
108            DataContainer::Empty => None,
109        }
110    }
111
112    #[must_use]
113    pub fn root_scopes(&self) -> Vec<ScopeType> {
114        match self {
115            DataContainer::Waves(w) => {
116                let scopes = w.root_scopes();
117                scopes
118                    .iter()
119                    .map(|s| ScopeType::WaveScope(s.clone()))
120                    .collect()
121            }
122            DataContainer::Transactions(_) => {
123                vec![ScopeType::StreamScope(StreamScopeRef::Root)]
124            }
125            DataContainer::Empty => vec![],
126        }
127    }
128
129    #[must_use]
130    pub fn scope_exists(&self, scope: &ScopeType) -> bool {
131        match (self, scope) {
132            (DataContainer::Waves(waves), WaveScope(scope)) => waves.scope_exists(scope),
133            (DataContainer::Transactions(transactions), StreamScope(scope)) => {
134                transactions.stream_scope_exists(scope)
135            }
136            (_, _) => false,
137        }
138    }
139
140    #[must_use]
141    pub fn scope_names(&self) -> Vec<String> {
142        match self {
143            DataContainer::Waves(w) => w.scope_names(),
144            DataContainer::Transactions(t) => t.stream_names(),
145            DataContainer::Empty => vec![],
146        }
147    }
148
149    #[must_use]
150    pub fn array_names(&self) -> Vec<String> {
151        match self {
152            DataContainer::Waves(w) => w.array_names(),
153            DataContainer::Transactions(_) => vec![],
154            DataContainer::Empty => vec![],
155        }
156    }
157
158    #[must_use]
159    pub fn variable_names(&self) -> Vec<String> {
160        match self {
161            DataContainer::Waves(w) => w.variable_names(),
162            DataContainer::Transactions(t) => t.generator_names(),
163            DataContainer::Empty => vec![],
164        }
165    }
166
167    #[must_use]
168    pub fn variables_in_scope(&self, scope: &ScopeType) -> Vec<VariableType> {
169        match (self, scope) {
170            (DataContainer::Waves(w), WaveScope(s)) => {
171                let variables = w.variables_in_scope(s);
172                variables
173                    .iter()
174                    .map(|v| VariableType::Variable(v.clone()))
175                    .collect()
176            }
177            (DataContainer::Transactions(t), StreamScope(s)) => {
178                let variables = t.generators_in_stream(s);
179                variables
180                    .iter()
181                    .map(|g| VariableType::Generator(g.clone()))
182                    .collect()
183            }
184            _ => panic!("Container and Scope are of incompatible types"),
185        }
186    }
187
188    #[must_use]
189    pub fn metadata(&self) -> MetaData {
190        match self {
191            DataContainer::Waves(w) => w.metadata(),
192            DataContainer::Transactions(t) => t.metadata(),
193            DataContainer::Empty => MetaData {
194                date: None,
195                version: None,
196                timescale: TimeScale {
197                    unit: TimeUnit::None,
198                    multiplier: None,
199                },
200            },
201        }
202    }
203
204    #[must_use]
205    pub fn body_loaded(&self) -> bool {
206        match self {
207            DataContainer::Waves(w) => w.body_loaded(),
208            DataContainer::Transactions(t) => t.body_loaded(),
209            DataContainer::Empty => true,
210        }
211    }
212
213    #[must_use]
214    pub fn is_fully_loaded(&self) -> bool {
215        match self {
216            DataContainer::Waves(w) => w.is_fully_loaded(),
217            DataContainer::Transactions(t) => t.is_fully_loaded(),
218            DataContainer::Empty => true,
219        }
220    }
221
222    #[must_use]
223    pub fn simulation_status(&self) -> Option<SimulationStatus> {
224        match self {
225            DataContainer::Waves(w) => w.simulation_status(),
226            DataContainer::Transactions(_) => None,
227            DataContainer::Empty => None,
228        }
229    }
230}