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!("{}[{}]", 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}