libsurfer/
data_container.rs1use 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}