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!("{}[{index}]", v.name)
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    #[must_use]
112    pub fn min_timestamp(&self) -> Option<BigUint> {
113        match self {
114            DataContainer::Waves(w) => w.min_timestamp(),
115            DataContainer::Transactions(_) => None,
116            DataContainer::Empty => None,
117        }
118    }
119
120    #[must_use]
121    pub fn root_scopes(&self) -> Vec<ScopeType> {
122        match self {
123            DataContainer::Waves(w) => {
124                let scopes = w.root_scopes();
125                scopes
126                    .iter()
127                    .map(|s| ScopeType::WaveScope(s.clone()))
128                    .collect()
129            }
130            DataContainer::Transactions(_) => {
131                vec![ScopeType::StreamScope(StreamScopeRef::Root)]
132            }
133            DataContainer::Empty => vec![],
134        }
135    }
136
137    #[must_use]
138    pub fn scope_exists(&self, scope: &ScopeType) -> bool {
139        match (self, scope) {
140            (DataContainer::Waves(waves), WaveScope(scope)) => waves.scope_exists(scope),
141            (DataContainer::Transactions(transactions), StreamScope(scope)) => {
142                transactions.stream_scope_exists(scope)
143            }
144            (_, _) => false,
145        }
146    }
147
148    #[must_use]
149    pub fn scope_names(&self) -> Vec<String> {
150        match self {
151            DataContainer::Waves(w) => w.scope_names(),
152            DataContainer::Transactions(t) => t.stream_names(),
153            DataContainer::Empty => vec![],
154        }
155    }
156
157    #[must_use]
158    pub fn array_names(&self) -> Vec<String> {
159        match self {
160            DataContainer::Waves(w) => w.array_names(),
161            DataContainer::Transactions(_) => vec![],
162            DataContainer::Empty => vec![],
163        }
164    }
165
166    #[must_use]
167    pub fn variable_names(&self) -> Vec<String> {
168        match self {
169            DataContainer::Waves(w) => w.variable_names(),
170            DataContainer::Transactions(t) => t.generator_names(),
171            DataContainer::Empty => vec![],
172        }
173    }
174
175    #[must_use]
176    pub fn variables_in_scope(&self, scope: &ScopeType) -> Vec<VariableType> {
177        match (self, scope) {
178            (DataContainer::Waves(w), WaveScope(s)) => {
179                let variables = w.variables_in_scope(s);
180                variables
181                    .iter()
182                    .map(|v| VariableType::Variable(v.clone()))
183                    .collect()
184            }
185            (DataContainer::Transactions(t), StreamScope(s)) => {
186                let variables = t.generators_in_stream(s);
187                variables
188                    .iter()
189                    .map(|g| VariableType::Generator(g.clone()))
190                    .collect()
191            }
192            _ => panic!("Container and Scope are of incompatible types"),
193        }
194    }
195
196    #[must_use]
197    pub fn metadata(&self) -> MetaData {
198        match self {
199            DataContainer::Waves(w) => w.metadata(),
200            DataContainer::Transactions(t) => t.metadata(),
201            DataContainer::Empty => MetaData {
202                date: None,
203                version: None,
204                timescale: TimeScale {
205                    unit: TimeUnit::None,
206                    multiplier: None,
207                },
208            },
209        }
210    }
211
212    #[must_use]
213    pub fn body_loaded(&self) -> bool {
214        match self {
215            DataContainer::Waves(w) => w.body_loaded(),
216            DataContainer::Transactions(t) => t.body_loaded(),
217            DataContainer::Empty => true,
218        }
219    }
220
221    #[must_use]
222    pub fn is_fully_loaded(&self) -> bool {
223        match self {
224            DataContainer::Waves(w) => w.is_fully_loaded(),
225            DataContainer::Transactions(t) => t.is_fully_loaded(),
226            DataContainer::Empty => true,
227        }
228    }
229
230    #[must_use]
231    pub fn simulation_status(&self) -> Option<SimulationStatus> {
232        match self {
233            DataContainer::Waves(w) => w.simulation_status(),
234            DataContainer::Transactions(_) => None,
235            DataContainer::Empty => None,
236        }
237    }
238}