1use core::fmt;
2
3#[allow(unused_imports)]
4use crate::prelude::*;
5use serde::{Deserialize, Serialize};
6
7use super::{
8 graph::{Graph, GraphEdge, GraphNode},
9 primitive::{Primitive, PrimitiveKind},
10 primitive_traits::{ApplyOp, OperatorError, Spreadable},
11 tuple::Tuple,
12};
13use crate::iterable_utils::flatten_primitive_array_values;
14use crate::parser::model_transformer::TransformError;
15use crate::traits::ToLatex;
16use crate::{
17 check_bounds,
18 math::{BinOp, UnOp},
19};
20#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
34#[serde(tag = "type", content = "value")]
35pub enum IterableKind {
36 Numbers(Vec<f64>),
38 Integers(Vec<i64>),
40 PositiveIntegers(Vec<u64>),
42 Strings(Vec<String>),
44 Edges(Vec<GraphEdge>),
46 Nodes(Vec<GraphNode>),
48 Graphs(Vec<Graph>),
50 Tuples(Vec<Tuple>),
52 Booleans(Vec<bool>),
54 Iterables(Vec<IterableKind>),
56 Anys(Vec<Primitive>),
58}
59
60#[cfg_attr(target_arch = "wasm32", wasm_bindgen(typescript_custom_section))]
61#[allow(non_upper_case_globals)]
62#[cfg(target_arch = "wasm32")]
63const IIterableKind: &'static str = r#"
64export type SerializedIterable =
65 | { type: 'Numbers', value: number[] }
66 | { type: 'Integers', value: number[] }
67 | { type: 'PositiveIntegers', value: number[] }
68 | { type: 'Strings', value: string[] }
69 | { type: 'Edges', value: SerializedGraphEdge[] }
70 | { type: 'Nodes', value: SerializedGraphNode[] }
71 | { type: 'Graphs', value: SerializedGraph[] }
72 | { type: 'Tuples', value: SerializedTuple[] }
73 | { type: 'Booleans', value: boolean[] }
74 | { type: 'Iterables', value: SerializedIterable[] }
75 | { type: 'Anys', value: SerializedPrimitive[] }
76"#;
77
78impl IterableKind {
79 pub fn get_type(&self) -> PrimitiveKind {
84 PrimitiveKind::Iterable(Box::new(self.inner_type()))
85 }
86
87 pub fn into_primitive(self) -> Primitive {
89 Primitive::Iterable(self)
90 }
91
92 pub fn flatten(self) -> IterableKind {
94 match self {
95 IterableKind::Anys(v) => flatten_primitive_array_values(v),
96 _ => self,
97 }
98 }
99
100 pub fn inner_type(&self) -> PrimitiveKind {
104 match self {
105 IterableKind::Numbers(_) => PrimitiveKind::Number,
106 IterableKind::Integers(_) => PrimitiveKind::Integer,
107 IterableKind::PositiveIntegers(_) => PrimitiveKind::PositiveInteger,
108 IterableKind::Strings(_) => PrimitiveKind::String,
109 IterableKind::Edges(_) => PrimitiveKind::GraphEdge,
110 IterableKind::Nodes(_) => PrimitiveKind::GraphNode,
111 IterableKind::Anys(_) => PrimitiveKind::Any,
112 IterableKind::Tuples(t) => t
113 .first()
114 .map(|e| e.get_type())
115 .unwrap_or(PrimitiveKind::Undefined),
116 IterableKind::Booleans(_) => PrimitiveKind::Boolean,
117 IterableKind::Graphs(_) => PrimitiveKind::Graph,
118 IterableKind::Iterables(i) => PrimitiveKind::Iterable(
119 i.first()
120 .map(|e| e.inner_type())
121 .unwrap_or(PrimitiveKind::Undefined)
122 .into(),
123 ),
124 }
125 }
126 pub fn len(&self) -> usize {
127 match self {
128 IterableKind::Numbers(v) => v.len(),
129 IterableKind::Integers(v) => v.len(),
130 IterableKind::PositiveIntegers(v) => v.len(),
131 IterableKind::Strings(v) => v.len(),
132 IterableKind::Edges(v) => v.len(),
133 IterableKind::Nodes(v) => v.len(),
134 IterableKind::Tuples(v) => v.len(),
135 IterableKind::Iterables(v) => v.len(),
136 IterableKind::Booleans(v) => v.len(),
137 IterableKind::Graphs(v) => v.len(),
138 IterableKind::Anys(v) => v.len(),
139 }
140 }
141 pub fn is_empty(&self) -> bool {
142 self.len() == 0
143 }
144
145 pub fn to_primitives(self) -> Vec<Primitive> {
147 match self {
148 IterableKind::Numbers(v) => v.iter().map(|n| Primitive::Number(*n)).collect(),
149 IterableKind::Integers(v) => v.iter().map(|n| Primitive::Integer(*n)).collect(),
150 IterableKind::PositiveIntegers(v) => {
151 v.iter().map(|n| Primitive::PositiveInteger(*n)).collect()
152 }
153 IterableKind::Anys(v) => v,
154 IterableKind::Strings(v) => v
155 .into_iter()
156 .map(|s| Primitive::String((*s).to_string()))
157 .collect(),
158 IterableKind::Edges(v) => v
159 .iter()
160 .map(|e| Primitive::GraphEdge(e.to_owned()))
161 .collect(),
162 IterableKind::Nodes(v) => v.into_iter().map(Primitive::GraphNode).collect(),
163 IterableKind::Tuples(v) => v.into_iter().map(Primitive::Tuple).collect(),
164 IterableKind::Iterables(v) => v.into_iter().map(Primitive::Iterable).collect(),
165 IterableKind::Booleans(v) => v.into_iter().map(Primitive::Boolean).collect(),
166 IterableKind::Graphs(v) => v.into_iter().map(Primitive::Graph).collect(),
167 }
168 }
169
170 pub fn read(&self, indexes: Vec<usize>) -> Result<Primitive, TransformError> {
181 if indexes.is_empty() {
182 return Ok(Primitive::Undefined);
183 }
184
185 let mut current = self;
186 let mut indexes = indexes;
187 while !indexes.is_empty() {
188 let i = indexes.remove(0);
189 let ended = indexes.is_empty();
190 if ended {
191 let val = match current {
192 IterableKind::Booleans(v) => {
193 check_bounds!(i, v, self, Primitive::Boolean(v[i]))
194 }
195 IterableKind::Anys(v) => check_bounds!(i, v, self, v[i].clone()),
196 IterableKind::Numbers(v) => check_bounds!(i, v, self, Primitive::Number(v[i])),
197 IterableKind::Integers(v) => {
198 check_bounds!(i, v, self, Primitive::Integer(v[i]))
199 }
200 IterableKind::PositiveIntegers(v) => {
201 check_bounds!(i, v, self, Primitive::PositiveInteger(v[i]))
202 }
203 IterableKind::Strings(v) => {
204 check_bounds!(i, v, self, Primitive::String(v[i].to_string()))
205 }
206 IterableKind::Edges(v) => {
207 check_bounds!(i, v, self, Primitive::GraphEdge(v[i].to_owned()))
208 }
209 IterableKind::Nodes(v) => {
210 check_bounds!(i, v, self, Primitive::GraphNode(v[i].to_owned()))
211 }
212 IterableKind::Tuples(v) => {
213 check_bounds!(i, v, self, Primitive::Tuple(v[i].clone()))
214 }
215 IterableKind::Iterables(v) => {
216 check_bounds!(i, v, self, Primitive::Iterable(v[i].clone()))
217 }
218 IterableKind::Graphs(v) => {
219 check_bounds!(i, v, self, Primitive::Graph(v[i].clone()))
220 }
221 };
222 return Ok(val);
223 } else {
224 match current {
225 IterableKind::Iterables(v) => {
226 if i < v.len() {
227 current = &v[i];
228 } else {
229 return Err(TransformError::OutOfBounds(format!(
230 "cannot access index {} of {}",
231 i, self
232 )));
233 }
234 }
235 _ => {
236 return Err(TransformError::OutOfBounds(format!(
237 "cannot access index {} of {}",
238 i, self
239 )));
240 }
241 }
242 }
243 }
244 Err(TransformError::OutOfBounds(format!(
245 "cannot access index {} of {}",
246 indexes[0], self
247 )))
248 }
249
250 pub fn depth(&self) -> usize {
255 let mut current = self;
256 let mut depth = 1;
257 while let IterableKind::Iterables(v) = current {
258 depth += 1;
259 match v.first() {
260 Some(i) => current = i,
261 None => break,
262 }
263 }
264 depth
265 }
266
267 pub fn to_string_depth(&self, depth: usize) -> String {
272 match self {
273 IterableKind::Iterables(v) => {
274 let s = v
275 .iter()
276 .map(|e| e.to_string_depth(depth + 1))
277 .collect::<Vec<_>>()
278 .join(", ");
279 format!("{}[\n{}\n]", " ".repeat(depth), s)
280 }
281 _ => format!("{}{}", " ".repeat(depth), self),
282 }
283 }
284
285 pub fn latexify(&self, include_block: bool) -> String {
290 match self {
291 IterableKind::Numbers(v) => latexify_vec(v, include_block),
292 IterableKind::Integers(v) => latexify_vec(v, include_block),
293 IterableKind::PositiveIntegers(v) => latexify_vec(v, include_block),
294 IterableKind::Anys(v) => latexify_vec(v, include_block),
295 IterableKind::Strings(v) => latexify_vec(v, include_block),
296 IterableKind::Edges(v) => latexify_vec(v, include_block),
297 IterableKind::Nodes(v) => latexify_vec(v, include_block),
298 IterableKind::Tuples(v) => latexify_vec(v, include_block),
299 IterableKind::Booleans(v) => latexify_vec(v, include_block),
300 IterableKind::Graphs(v) => latexify_vec(v, include_block),
301 IterableKind::Iterables(v) => {
302 let s = v
303 .iter()
304 .map(|i| i.to_latex())
305 .collect::<Vec<_>>()
306 .join("\\\\");
307 if include_block {
308 format!("\\begin{{bmatrix}} {} \\end{{bmatrix}}", s)
309 } else {
310 s.to_string()
311 }
312 }
313 }
314 }
315}
316fn latexify_vec<T>(v: &[T], include_block: bool) -> String
317where
318 T: ToLatex,
319{
320 let values = v
321 .iter()
322 .map(|e| e.to_latex())
323 .collect::<Vec<_>>()
324 .join(" & ");
325 if include_block {
326 format!("\\begin{{bmatrix}} {} \\end{{bmatrix}}", values)
327 } else {
328 values.to_string()
329 }
330}
331
332impl ToLatex for IterableKind {
333 fn to_latex(&self) -> String {
334 match self {
335 IterableKind::Iterables(v) => {
336 let depth = self.depth();
337 if depth == 2 {
338 let items = v
340 .iter()
341 .map(|i| i.latexify(false))
342 .collect::<Vec<_>>()
343 .join(" \\\\ ");
344 format!("\\begin{{bmatrix}} {} \\end{{bmatrix}}", items)
345 } else {
346 self.latexify(true)
347 }
348 }
349 _ => self.latexify(true),
350 }
351 }
352}
353
354impl fmt::Display for IterableKind {
355 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
356 let s = match self {
358 IterableKind::Numbers(v) => format!("{:?}", v),
359 IterableKind::Integers(v) => format!("{:?}", v),
360 IterableKind::Anys(v) => format!("{:?}", v),
361 IterableKind::PositiveIntegers(v) => format!("{:?}", v),
362 IterableKind::Strings(v) => format!("{:?}", v),
363 IterableKind::Edges(v) => format!("{:?}", v),
364 IterableKind::Nodes(v) => format!("{:?}", v),
365 IterableKind::Tuples(v) => format!("{:?}", v),
366 IterableKind::Booleans(v) => format!("{:?}", v),
367 IterableKind::Graphs(v) => format!("{:?}", v),
368 IterableKind::Iterables(v) => {
369 let result = v
370 .iter()
371 .map(|i| i.to_string_depth(1))
372 .collect::<Vec<_>>()
373 .join(",\n");
374 format!("[\n{}\n]", result)
375 }
376 };
377 f.write_str(&s)
378 }
379}
380
381impl ApplyOp for IterableKind {
382 type TargetType = PrimitiveKind;
383 type Target = Primitive;
384 type Error = OperatorError;
385 fn apply_binary_op(&self, op: BinOp, _to: &Primitive) -> Result<Primitive, OperatorError> {
386 Err(OperatorError::unsupported_bin_operation(op, _to.get_type()))
387 }
388 fn apply_unary_op(&self, op: UnOp) -> Result<Self::Target, Self::Error> {
389 Err(OperatorError::unsupported_un_operation(
390 op,
391 self.inner_type(),
392 ))
393 }
394 fn can_apply_binary_op(_: BinOp, _: Self::TargetType) -> bool {
395 false
396 }
397 fn can_apply_unary_op(_: UnOp) -> bool {
398 false
399 }
400}
401
402impl Spreadable for IterableKind {
403 fn to_primitive_set(self) -> Result<Vec<Primitive>, TransformError> {
404 Ok(self.to_primitives())
405 }
406}