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
31impl DataContainer {
32    #[must_use]
33    pub fn __new_empty() -> Self {
34        DataContainer::Empty
35    }
36
37    #[must_use]
38    pub fn as_waves(&self) -> Option<&WaveContainer> {
39        match self {
40            DataContainer::Waves(w) => Some(w),
41            DataContainer::Transactions(_) => None,
42            DataContainer::Empty => None,
43        }
44    }
45
46    pub fn as_waves_mut(&mut self) -> Option<&mut WaveContainer> {
47        match self {
48            DataContainer::Waves(w) => Some(w),
49            DataContainer::Transactions(_) => None,
50            DataContainer::Empty => None,
51        }
52    }
53
54    #[must_use]
55    pub fn as_transactions(&self) -> Option<&TransactionContainer> {
56        match self {
57            DataContainer::Waves(_) => None,
58            DataContainer::Transactions(t) => Some(t),
59            DataContainer::Empty => None,
60        }
61    }
62
63    pub fn as_transactions_mut(&mut self) -> Option<&mut TransactionContainer> {
64        match self {
65            DataContainer::Waves(_) => None,
66            DataContainer::Transactions(t) => Some(t),
67            DataContainer::Empty => None,
68        }
69    }
70
71    #[must_use]
72    pub fn is_waves(&self) -> bool {
73        match self {
74            DataContainer::Waves(_) => true,
75            DataContainer::Transactions(_) => false,
76            DataContainer::Empty => false,
77        }
78    }
79
80    #[must_use]
81    pub fn is_transactions(&self) -> bool {
82        match self {
83            DataContainer::Waves(_) => false,
84            DataContainer::Transactions(_) => true,
85            DataContainer::Empty => false,
86        }
87    }
88
89    #[must_use]
90    pub fn max_timestamp(&self) -> Option<BigUint> {
91        match self {
92            DataContainer::Waves(w) => w.max_timestamp(),
93            DataContainer::Transactions(t) => t.max_timestamp(),
94            DataContainer::Empty => None,
95        }
96    }
97
98    #[must_use]
99    pub fn root_scopes(&self) -> Vec<ScopeType> {
100        match self {
101            DataContainer::Waves(w) => {
102                let scopes = w.root_scopes();
103                scopes
104                    .iter()
105                    .map(|s| ScopeType::WaveScope(s.clone()))
106                    .collect()
107            }
108            DataContainer::Transactions(_) => {
109                vec![ScopeType::StreamScope(StreamScopeRef::Root)]
110            }
111            DataContainer::Empty => vec![],
112        }
113    }
114
115    #[must_use]
116    pub fn scope_exists(&self, scope: &ScopeType) -> bool {
117        match (self, scope) {
118            (DataContainer::Waves(waves), WaveScope(scope)) => waves.scope_exists(scope),
119            (DataContainer::Transactions(transactions), StreamScope(scope)) => {
120                transactions.stream_scope_exists(scope)
121            }
122            (_, _) => false,
123        }
124    }
125
126    #[must_use]
127    pub fn scope_names(&self) -> Vec<String> {
128        match self {
129            DataContainer::Waves(w) => w.scope_names(),
130            DataContainer::Transactions(t) => t.stream_names(),
131            DataContainer::Empty => vec![],
132        }
133    }
134
135    #[must_use]
136    pub fn variable_names(&self) -> Vec<String> {
137        match self {
138            DataContainer::Waves(w) => w.variable_names(),
139            DataContainer::Transactions(t) => t.generator_names(),
140            DataContainer::Empty => vec![],
141        }
142    }
143
144    #[must_use]
145    pub fn variables_in_scope(&self, scope: &ScopeType) -> Vec<VariableType> {
146        match (self, scope) {
147            (DataContainer::Waves(w), WaveScope(s)) => {
148                let variables = w.variables_in_scope(s);
149                variables
150                    .iter()
151                    .map(|v| VariableType::Variable(v.clone()))
152                    .collect()
153            }
154            (DataContainer::Transactions(t), StreamScope(s)) => {
155                let variables = t.generators_in_stream(s);
156                variables
157                    .iter()
158                    .map(|g| VariableType::Generator(g.clone()))
159                    .collect()
160            }
161            _ => panic!("Container and Scope are of incompatible types"),
162        }
163    }
164
165    #[must_use]
166    pub fn metadata(&self) -> MetaData {
167        match self {
168            DataContainer::Waves(w) => w.metadata(),
169            DataContainer::Transactions(t) => t.metadata(),
170            DataContainer::Empty => MetaData {
171                date: None,
172                version: None,
173                timescale: TimeScale {
174                    unit: TimeUnit::None,
175                    multiplier: None,
176                },
177            },
178        }
179    }
180
181    #[must_use]
182    pub fn body_loaded(&self) -> bool {
183        match self {
184            DataContainer::Waves(w) => w.body_loaded(),
185            DataContainer::Transactions(t) => t.body_loaded(),
186            DataContainer::Empty => true,
187        }
188    }
189
190    #[must_use]
191    pub fn is_fully_loaded(&self) -> bool {
192        match self {
193            DataContainer::Waves(w) => w.is_fully_loaded(),
194            DataContainer::Transactions(t) => t.is_fully_loaded(),
195            DataContainer::Empty => true,
196        }
197    }
198
199    #[must_use]
200    pub fn simulation_status(&self) -> Option<SimulationStatus> {
201        match self {
202            DataContainer::Waves(w) => w.simulation_status(),
203            DataContainer::Transactions(_) => None,
204            DataContainer::Empty => None,
205        }
206    }
207}