1use crate::*;
2use super::*;
3#[cfg(feature = "matrix")]
4use crate::structures::Matrix;
5
6pub trait CompileConst {
10 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32>;
11}
12
13#[cfg(feature = "compiler")]
14impl CompileConst for Value {
15
16 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
17 let reg = match self {
18 #[cfg(feature = "bool")]
19 Value::Bool(x) => x.borrow().compile_const(ctx)?,
20 #[cfg(feature = "string")]
21 Value::String(x) => x.borrow().compile_const(ctx)?,
22 #[cfg(feature = "u8")]
23 Value::U8(x) => x.borrow().compile_const(ctx)?,
24 #[cfg(feature = "u16")]
25 Value::U16(x) => x.borrow().compile_const(ctx)?,
26 #[cfg(feature = "u32")]
27 Value::U32(x) => x.borrow().compile_const(ctx)?,
28 #[cfg(feature = "u64")]
29 Value::U64(x) => x.borrow().compile_const(ctx)?,
30 #[cfg(feature = "u128")]
31 Value::U128(x) => x.borrow().compile_const(ctx)?,
32 #[cfg(feature = "i8")]
33 Value::I8(x) => x.borrow().compile_const(ctx)?,
34 #[cfg(feature = "i16")]
35 Value::I16(x) => x.borrow().compile_const(ctx)?,
36 #[cfg(feature = "i32")]
37 Value::I32(x) => x.borrow().compile_const(ctx)?,
38 #[cfg(feature = "i64")]
39 Value::I64(x) => x.borrow().compile_const(ctx)?,
40 #[cfg(feature = "i128")]
41 Value::I128(x) => x.borrow().compile_const(ctx)?,
42 #[cfg(feature = "f32")]
43 Value::F32(x) => x.borrow().compile_const(ctx)?,
44 #[cfg(feature = "f64")]
45 Value::F64(x) => x.borrow().compile_const(ctx)?,
46 #[cfg(feature = "atom")]
47 Value::Atom(x) => x.borrow().compile_const(ctx)?,
48 #[cfg(feature = "index")]
49 Value::Index(x) => x.borrow().compile_const(ctx)?,
50 #[cfg(feature = "complex")]
51 Value::C64(x) => x.borrow().compile_const(ctx)?,
52 #[cfg(feature = "rational")]
53 Value::R64(x) => x.borrow().compile_const(ctx)?,
54 #[cfg(all(feature = "matrix", feature = "f64"))]
55 Value::MatrixF64(x) => x.compile_const(ctx)?,
56 #[cfg(all(feature = "matrix", feature = "f32"))]
57 Value::MatrixF32(x) => x.compile_const(ctx)?,
58 #[cfg(all(feature = "matrix", feature = "u8"))]
59 Value::MatrixU8(x) => x.compile_const(ctx)?,
60 #[cfg(all(feature = "matrix", feature = "u16"))]
61 Value::MatrixU16(x) => x.compile_const(ctx)?,
62 #[cfg(all(feature = "matrix", feature = "u32"))]
63 Value::MatrixU32(x) => x.compile_const(ctx)?,
64 #[cfg(all(feature = "matrix", feature = "u64"))]
65 Value::MatrixU64(x) => x.compile_const(ctx)?,
66 #[cfg(all(feature = "matrix", feature = "u128"))]
67 Value::MatrixU128(x) => x.compile_const(ctx)?,
68 #[cfg(all(feature = "matrix", feature = "i8"))]
69 Value::MatrixI8(x) => x.compile_const(ctx)?,
70 #[cfg(all(feature = "matrix", feature = "i16"))]
71 Value::MatrixI16(x) => x.compile_const(ctx)?,
72 #[cfg(all(feature = "matrix", feature = "i32"))]
73 Value::MatrixI32(x) => x.compile_const(ctx)?,
74 #[cfg(all(feature = "matrix", feature = "i64"))]
75 Value::MatrixI64(x) => x.compile_const(ctx)?,
76 #[cfg(all(feature = "matrix", feature = "i128"))]
77 Value::MatrixI128(x) => x.compile_const(ctx)?,
78 #[cfg(all(feature = "matrix", feature = "bool"))]
79 Value::MatrixBool(x) => x.compile_const(ctx)?,
80 #[cfg(all(feature = "matrix", feature = "rational"))]
81 Value::MatrixR64(x) => x.compile_const(ctx)?,
82 #[cfg(all(feature = "matrix", feature = "complex"))]
83 Value::MatrixC64(x) => x.compile_const(ctx)?,
84 #[cfg(all(feature = "matrix", feature = "string"))]
85 Value::MatrixString(x) => x.compile_const(ctx)?,
86 #[cfg(feature = "matrix")]
87 Value::MatrixIndex(x) => x.compile_const(ctx)?,
88 #[cfg(feature = "matrix")]
89 Value::MatrixValue(x) => x.compile_const(ctx)?,
90 #[cfg(feature = "table")]
91 Value::Table(x) => x.borrow().compile_const(ctx)?,
92 _ => todo!(),
93 };
94 Ok(reg)
95 }
96}
97
98#[cfg(feature = "f64")]
99impl CompileConst for F64 {
100 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
101 let mut payload = Vec::<u8>::new();
102 payload.write_f64::<LittleEndian>(self.0)?;
103 ctx.compile_const(&payload, ValueKind::F64)
104 }
105}
106
107#[cfg(feature = "f32")]
108impl CompileConst for F32 {
109 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
110 let mut payload = Vec::<u8>::new();
111 payload.write_f32::<LittleEndian>(self.0)?;
112 ctx.compile_const(&payload, ValueKind::F32)
113 }
114}
115
116#[cfg(feature = "u8")]
117impl CompileConst for u8 {
118 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
119 let mut payload = Vec::<u8>::new();
120 payload.write_u8(*self)?;
121 ctx.compile_const(&payload, ValueKind::U8)
122 }
123}
124
125#[cfg(feature = "i8")]
126impl CompileConst for i8 {
127 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
128 let mut payload = Vec::<u8>::new();
129 payload.write_i8(*self)?;
130 ctx.compile_const(&payload, ValueKind::I8)
131 }
132}
133
134impl CompileConst for usize {
135 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
136 let mut payload = Vec::<u8>::new();
137 payload.write_u64::<LittleEndian>(*self as u64)?;
138 ctx.compile_const(&payload, ValueKind::Index)
139 }
140}
141
142macro_rules! impl_compile_const {
143 ($feature:literal, $t:tt) => {
144 paste! {
145 #[cfg(feature = $feature)]
146 impl CompileConst for $t {
147 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
148 let mut payload = Vec::<u8>::new();
149 payload.[<write_ $t>]::<LittleEndian>(*self)?;
150 ctx.compile_const(&payload, ValueKind::[<$t:upper>])
151 }
152 }
153 }
154 };
155}
156
157#[cfg(feature = "u16")]
158impl_compile_const!("u16", u16);
159#[cfg(feature = "u32")]
160impl_compile_const!("u32", u32);
161#[cfg(feature = "u64")]
162impl_compile_const!("u64", u64);
163#[cfg(feature = "u128")]
164impl_compile_const!("u128", u128);
165#[cfg(feature = "i16")]
166impl_compile_const!("i16", i16);
167#[cfg(feature = "i32")]
168impl_compile_const!("i32", i32);
169#[cfg(feature = "i64")]
170impl_compile_const!("i64", i64);
171#[cfg(feature = "i128")]
172impl_compile_const!("i128", i128);
173
174#[cfg(feature = "bool")]
175impl CompileConst for bool {
176 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
177 let mut payload = Vec::<u8>::new();
178 payload.write_u8(if *self { 1 } else { 0 })?;
179 ctx.compile_const(&payload, ValueKind::Bool)
180 }
181}
182
183#[cfg(feature = "string")]
184impl CompileConst for String {
185 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
186 let mut payload = Vec::<u8>::new();
187 payload.write_u32::<LittleEndian>(self.len() as u32)?;
188 payload.extend_from_slice(self.as_bytes());
189 ctx.compile_const(&payload, ValueKind::String)
190 }
191}
192
193#[cfg(feature = "rational")]
194impl CompileConst for R64 {
195 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
196 let mut payload = Vec::<u8>::new();
197 payload.write_i64::<LittleEndian>(*self.numer())?;
198 payload.write_i64::<LittleEndian>(*self.denom())?;
199 ctx.compile_const(&payload, ValueKind::R64)
200 }
201}
202
203#[cfg(feature = "complex")]
204impl CompileConst for C64 {
205 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
206 let mut payload = Vec::<u8>::new();
207 payload.write_f64::<LittleEndian>(self.0.re)?;
208 payload.write_f64::<LittleEndian>(self.0.im)?;
209 ctx.compile_const(&payload, ValueKind::C64)
210 }
211}
212
213macro_rules! impl_compile_const_matrix {
214 ($matrix_type:ty) => {
215 impl<T> CompileConst for $matrix_type
216 where
217 T: ConstElem,
218 {
219 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
220 let rows = self.nrows() as u32;
221 let cols = self.ncols() as u32;
222 let mut payload = Vec::<u8>::with_capacity((rows * cols) as usize * 8);
223
224 payload.write_u32::<LittleEndian>(rows)?;
226 payload.write_u32::<LittleEndian>(cols)?;
227
228 for c in 0..cols as usize {
230 for r in 0..rows as usize {
231 self[(r, c)].write_le(&mut payload);
232 }
233 }
234 let elem_vk = T::value_kind();
235 let mat_vk = ValueKind::Matrix(Box::new(elem_vk), vec![rows as usize, cols as usize]);
236 ctx.compile_const(&payload, mat_vk)
237 }
238 }
239 };
240}
241
242#[cfg(feature = "matrix1")]
243impl_compile_const_matrix!(na::Matrix1<T>);
244#[cfg(feature = "matrix2")]
245impl_compile_const_matrix!(na::Matrix2<T>);
246#[cfg(feature = "matrix3")]
247impl_compile_const_matrix!(na::Matrix3<T>);
248#[cfg(feature = "matrix4")]
249impl_compile_const_matrix!(na::Matrix4<T>);
250#[cfg(feature = "matrix2x3")]
251impl_compile_const_matrix!(na::Matrix2x3<T>);
252#[cfg(feature = "matrix3x2")]
253impl_compile_const_matrix!(na::Matrix3x2<T>);
254#[cfg(feature = "row_vector2")]
255impl_compile_const_matrix!(na::RowVector2<T>);
256#[cfg(feature = "row_vector3")]
257impl_compile_const_matrix!(na::RowVector3<T>);
258#[cfg(feature = "row_vector4")]
259impl_compile_const_matrix!(na::RowVector4<T>);
260#[cfg(feature = "vector2")]
261impl_compile_const_matrix!(na::Vector2<T>);
262#[cfg(feature = "vector3")]
263impl_compile_const_matrix!(na::Vector3<T>);
264#[cfg(feature = "vector4")]
265impl_compile_const_matrix!(na::Vector4<T>);
266#[cfg(feature = "matrixd")]
267impl_compile_const_matrix!(na::DMatrix<T>);
268#[cfg(feature = "vectord")]
269impl_compile_const_matrix!(na::DVector<T>);
270#[cfg(feature = "row_vectord")]
271impl_compile_const_matrix!(na::RowDVector<T>);
272
273#[cfg(feature = "matrix")]
274impl<T> CompileConst for Matrix<T>
275where
276 T: CompileConst + ConstElem
277{
278 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
279 match self {
280 #[cfg(feature = "matrixd")]
281 Matrix::DMatrix(mat) => mat.borrow().compile_const(ctx),
282 #[cfg(feature = "vectord")]
283 Matrix::DVector(mat) => mat.borrow().compile_const(ctx),
284 #[cfg(feature = "row_vectord")]
285 Matrix::RowDVector(mat) => mat.borrow().compile_const(ctx),
286 #[cfg(feature = "matrix1")]
287 Matrix::Matrix1(mat) => mat.borrow().compile_const(ctx),
288 #[cfg(feature = "matrix2")]
289 Matrix::Matrix2(mat) => mat.borrow().compile_const(ctx),
290 #[cfg(feature = "matrix3")]
291 Matrix::Matrix3(mat) => mat.borrow().compile_const(ctx),
292 #[cfg(feature = "matrix4")]
293 Matrix::Matrix4(mat) => mat.borrow().compile_const(ctx),
294 #[cfg(feature = "matrix2x3")]
295 Matrix::Matrix2x3(mat) => mat.borrow().compile_const(ctx),
296 #[cfg(feature = "matrix3x2")]
297 Matrix::Matrix3x2(mat) => mat.borrow().compile_const(ctx),
298 #[cfg(feature = "row_vector2")]
299 Matrix::RowVector2(mat) => mat.borrow().compile_const(ctx),
300 #[cfg(feature = "row_vector3")]
301 Matrix::RowVector3(mat) => mat.borrow().compile_const(ctx),
302 #[cfg(feature = "row_vector4")]
303 Matrix::RowVector4(mat) => mat.borrow().compile_const(ctx),
304 #[cfg(feature = "vector2")]
305 Matrix::Vector2(mat) => mat.borrow().compile_const(ctx),
306 #[cfg(feature = "vector3")]
307 Matrix::Vector3(mat) => mat.borrow().compile_const(ctx),
308 #[cfg(feature = "vector4")]
309 Matrix::Vector4(mat) => mat.borrow().compile_const(ctx),
310 }
311 }
312}
313
314#[cfg(feature = "matrixd")]
315impl<T> CompileConst for Ref<DMatrix<T>>
316where
317 T: CompileConst + ConstElem
318{
319 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
320 self.borrow().compile_const(ctx)
321 }
322}
323
324#[cfg(feature = "vectord")]
325impl<T> CompileConst for Ref<DVector<T>>
326where
327 T: CompileConst + ConstElem
328{
329 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
330 self.borrow().compile_const(ctx)
331 }
332}
333
334#[cfg(feature = "row_vectord")]
335impl<T> CompileConst for Ref<RowDVector<T>>
336where
337 T: CompileConst + ConstElem
338{
339 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
340 self.borrow().compile_const(ctx)
341 }
342}
343
344#[cfg(feature = "table")]
345impl CompileConst for MechTable {
346 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
347 let mut payload = Vec::<u8>::new();
348
349 payload.write_u32::<LittleEndian>(self.rows as u32)?;
351 payload.write_u32::<LittleEndian>(self.cols as u32)?;
352
353 for (col_id, (vk, col_data)) in self.data.iter() {
355 payload.write_u64::<LittleEndian>(*col_id)?;
357 let value_kind = col_data.index1d(0).kind();
359 value_kind.write_le(&mut payload);
360
361 col_data.write_le(&mut payload);
363 }
364
365 for (_col_id, col_name) in self.col_names.iter() {
367 col_name.write_le(&mut payload);
368 }
369 ctx.compile_const(&payload, self.kind())
370 }
371}
372
373#[cfg(feature = "record")]
374impl CompileConst for MechRecord {
375 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
376 let mut payload = Vec::<u8>::new();
377
378 payload.write_u32::<LittleEndian>(self.cols as u32)?;
380
381 for (col_id, value) in self.data.iter() {
383 payload.write_u64::<LittleEndian>(*col_id)?;
385 let value_kind = value.kind();
387 value_kind.write_le(&mut payload);
388 value.write_le(&mut payload);
390 }
391
392 for (_col_id, col_name) in self.field_names.iter() {
394 col_name.write_le(&mut payload);
395 }
396 ctx.compile_const(&payload, self.kind())
397 }
398}
399
400#[cfg(feature = "enum")]
401impl CompileConst for MechEnum {
402 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
403 let mut payload = Vec::<u8>::new();
404
405 payload.write_u64::<LittleEndian>(self.id)?;
407
408 payload.write_u32::<LittleEndian>(self.variants.len() as u32)?;
410
411 for (variant_id, variant_value) in self.variants.iter() {
413 payload.write_u64::<LittleEndian>(*variant_id)?;
415 match variant_value {
416 Some(v) => {
417 payload.write_u8(1)?;
419 let value_kind = v.kind();
421 value_kind.write_le(&mut payload);
422 v.write_le(&mut payload);
424 },
425 None => {
426 payload.write_u8(0)?;
428 }
429 }
430 }
431 ctx.compile_const(&payload, ValueKind::Enum(self.id))
432 }
433}
434
435#[cfg(feature = "atom")]
436impl CompileConst for MechAtom {
437 fn compile_const(&self, ctx: &mut CompileCtx) -> MResult<u32> {
438 let mut payload = Vec::<u8>::new();
439 payload.write_u64::<LittleEndian>(self.0)?;
440 ctx.compile_const(&payload, ValueKind::Atom(self.0))
441 }
442}
443
444pub trait ConstElem {
448 fn write_le(&self, out: &mut Vec<u8>);
449 fn value_kind() -> ValueKind;
450 fn align() -> u8 { 1 }
451}
452
453#[cfg(feature = "f64")]
454impl ConstElem for F64 {
455 fn write_le(&self, out: &mut Vec<u8>) {
456 out.write_f64::<LittleEndian>(self.0).expect("write f64");
457 }
458 fn value_kind() -> ValueKind { ValueKind::F64 }
459 fn align() -> u8 { 8 }
460}
461
462#[cfg(feature = "f32")]
463impl ConstElem for F32 {
464 fn write_le(&self, out: &mut Vec<u8>) {
465 out.write_f32::<LittleEndian>(self.0).expect("write f32");
466 }
467 fn value_kind() -> ValueKind { ValueKind::F32 }
468 fn align() -> u8 { 4 }
469}
470
471macro_rules! impl_const_elem {
472 ($feature:literal, $t:ty, $align:expr) => {
473 paste!{
474 #[cfg(feature = $feature)]
475 impl ConstElem for $t {
476 fn write_le(&self, out: &mut Vec<u8>) {
477 out.[<write_ $t>]::<LittleEndian>(*self).expect(concat!("write ", stringify!($t)));
478 }
479 fn value_kind() -> ValueKind { ValueKind::[<$t:upper>] }
480 fn align() -> u8 { $align }
481 }
482 }
483 };
484}
485
486#[cfg(feature = "u16")]
487impl_const_elem!("u16", u16, 2);
488#[cfg(feature = "u32")]
489impl_const_elem!("u32", u32, 4);
490#[cfg(feature = "u64")]
491impl_const_elem!("u64", u64, 8);
492#[cfg(feature = "u128")]
493impl_const_elem!("u128", u128, 16);
494#[cfg(feature = "i16")]
495impl_const_elem!("i16", i16, 2);
496#[cfg(feature = "i32")]
497impl_const_elem!("i32", i32, 4);
498#[cfg(feature = "i64")]
499impl_const_elem!("i64", i64, 8);
500#[cfg(feature = "i128")]
501impl_const_elem!("i128", i128, 16);
502
503#[cfg(feature = "u8")]
504impl ConstElem for u8 {
505 fn write_le(&self, out: &mut Vec<u8>) {
506 out.write_u8(*self).expect("write u8");
507 }
508 fn value_kind() -> ValueKind { ValueKind::U8 }
509 fn align() -> u8 { 1 }
510}
511
512#[cfg(feature = "i8")]
513impl ConstElem for i8 {
514 fn write_le(&self, out: &mut Vec<u8>) {
515 out.write_i8(*self).expect("write i8");
516 }
517 fn value_kind() -> ValueKind { ValueKind::I8 }
518 fn align() -> u8 { 1 }
519}
520
521#[cfg(feature = "rational")]
522impl ConstElem for R64 {
523 fn write_le(&self, out: &mut Vec<u8>) {
524 out.write_i64::<LittleEndian>(*self.numer()).expect("write rational numer");
525 out.write_i64::<LittleEndian>(*self.denom()).expect("write rational denom");
526 }
527 fn value_kind() -> ValueKind { ValueKind::R64 }
528 fn align() -> u8 { 16 }
529}
530
531#[cfg(feature = "complex")]
532impl ConstElem for C64 {
533 fn write_le(&self, out: &mut Vec<u8>) {
534 out.write_f64::<LittleEndian>(self.0.re).expect("write complex real");
535 out.write_f64::<LittleEndian>(self.0.im).expect("write complex imag");
536 }
537 fn value_kind() -> ValueKind { ValueKind::C64 }
538 fn align() -> u8 { 16 }
539}
540
541#[cfg(feature = "string")]
542impl ConstElem for String {
543 fn write_le(&self, out: &mut Vec<u8>) {
544 out.write_u32::<LittleEndian>(self.len() as u32).expect("write string length");
545 out.extend_from_slice(self.as_bytes());
546 }
547 fn value_kind() -> ValueKind { ValueKind::String }
548 fn align() -> u8 { 1 }
549}
550
551#[cfg(feature = "bool")]
552impl ConstElem for bool {
553 fn write_le(&self, out: &mut Vec<u8>) {
554 out.write_u8(if *self { 1 } else { 0 }).expect("write bool");
555 }
556 fn value_kind() -> ValueKind { ValueKind::Bool }
557 fn align() -> u8 { 1 }
558}
559
560impl ConstElem for usize {
561 fn write_le(&self, out: &mut Vec<u8>) {
562 out.write_u64::<LittleEndian>(*self as u64).expect("write usize");
563 }
564 fn value_kind() -> ValueKind { ValueKind::Index }
565 fn align() -> u8 { 8 }
566}
567
568macro_rules! impl_const_elem_matrix {
569 ($matrix_type:ty, $rows:expr, $cols:expr) => {
570 impl<T> ConstElem for $matrix_type
571 where
572 T: ConstElem
573 {
574 fn write_le(&self, out: &mut Vec<u8>) {
575 for c in 0..self.ncols() {
576 for r in 0..self.nrows() {
577 self[(r, c)].write_le(out);
578 }
579 }
580 }
581 fn value_kind() -> ValueKind { ValueKind::Matrix(Box::new(T::value_kind()), vec![$rows, $cols]) }
582 fn align() -> u8 { 8 }
583 }
584 };
585}
586
587#[cfg(feature = "matrix1")]
588impl_const_elem_matrix!(Matrix1<T>, 1, 1);
589#[cfg(feature = "matrix2")]
590impl_const_elem_matrix!(Matrix2<T>, 2, 2);
591#[cfg(feature = "matrix3")]
592impl_const_elem_matrix!(Matrix3<T>, 3, 3);
593#[cfg(feature = "matrix4")]
594impl_const_elem_matrix!(Matrix4<T>, 4, 4);
595#[cfg(feature = "matrix2x3")]
596impl_const_elem_matrix!(Matrix2x3<T>, 2, 3);
597#[cfg(feature = "matrix3x2")]
598impl_const_elem_matrix!(Matrix3x2<T>, 3, 2);
599#[cfg(feature = "row_vector2")]
600impl_const_elem_matrix!(RowVector2<T>, 1, 2);
601#[cfg(feature = "row_vector3")]
602impl_const_elem_matrix!(RowVector3<T>, 1, 3);
603#[cfg(feature = "row_vector4")]
604impl_const_elem_matrix!(RowVector4<T>, 1, 4);
605#[cfg(feature = "vector2")]
606impl_const_elem_matrix!(Vector2<T>, 2, 1);
607#[cfg(feature = "vector3")]
608impl_const_elem_matrix!(Vector3<T>, 3, 1);
609#[cfg(feature = "vector4")]
610impl_const_elem_matrix!(Vector4<T>, 4, 1);
611#[cfg(feature = "matrixd")]
612impl_const_elem_matrix!(DMatrix<T>, 0, 0);
613#[cfg(feature = "vectord")]
614impl_const_elem_matrix!(DVector<T>, 0, 1);
615#[cfg(feature = "row_vectord")]
616impl_const_elem_matrix!(RowDVector<T>, 1, 0);
617
618impl<T> ConstElem for Matrix<T>
619where
620 T: ConstElem
621{
622 fn write_le(&self, out: &mut Vec<u8>) {
623 match self {
624 #[cfg(feature = "matrixd")]
625 Matrix::DMatrix(mat) => mat.borrow().write_le(out),
626 #[cfg(feature = "vectord")]
627 Matrix::DVector(mat) => mat.borrow().write_le(out),
628 #[cfg(feature = "row_vectord")]
629 Matrix::RowDVector(mat) => mat.borrow().write_le(out),
630 #[cfg(feature = "matrix1")]
631 Matrix::Matrix1(mat) => mat.borrow().write_le(out),
632 #[cfg(feature = "matrix2")]
633 Matrix::Matrix2(mat) => mat.borrow().write_le(out),
634 #[cfg(feature = "matrix3")]
635 Matrix::Matrix3(mat) => mat.borrow().write_le(out),
636 #[cfg(feature = "matrix4")]
637 Matrix::Matrix4(mat) => mat.borrow().write_le(out),
638 #[cfg(feature = "matrix2x3")]
639 Matrix::Matrix2x3(mat) => mat.borrow().write_le(out),
640 #[cfg(feature = "matrix3x2")]
641 Matrix::Matrix3x2(mat) => mat.borrow().write_le(out),
642 #[cfg(feature = "row_vector2")]
643 Matrix::RowVector2(mat) => mat.borrow().write_le(out),
644 #[cfg(feature = "row_vector3")]
645 Matrix::RowVector3(mat) => mat.borrow().write_le(out),
646 #[cfg(feature = "row_vector4")]
647 Matrix::RowVector4(mat) => mat.borrow().write_le(out),
648 #[cfg(feature = "vector2")]
649 Matrix::Vector2(mat) => mat.borrow().write_le(out),
650 #[cfg(feature = "vector3")]
651 Matrix::Vector3(mat) => mat.borrow().write_le(out),
652 #[cfg(feature = "vector4")]
653 Matrix::Vector4(mat) => mat.borrow().write_le(out),
654 }
655 }
656 fn value_kind() -> ValueKind { ValueKind::Matrix(Box::new(T::value_kind()), vec![0,0]) }
657 fn align() -> u8 { T::align() }
658}
659
660
661impl ConstElem for Value {
662 fn write_le(&self, out: &mut Vec<u8>) {
663 match self {
664 #[cfg(feature = "bool")]
665 Value::Bool(x) => x.borrow().write_le(out),
666 #[cfg(feature = "string")]
667 Value::String(x) => x.borrow().write_le(out),
668 #[cfg(feature = "u8")]
669 Value::U8(x) => x.borrow().write_le(out),
670 #[cfg(feature = "u16")]
671 Value::U16(x) => x.borrow().write_le(out),
672 #[cfg(feature = "u32")]
673 Value::U32(x) => x.borrow().write_le(out),
674 #[cfg(feature = "u64")]
675 Value::U64(x) => x.borrow().write_le(out),
676 #[cfg(feature = "u128")]
677 Value::U128(x) => x.borrow().write_le(out),
678 #[cfg(feature = "i8")]
679 Value::I8(x) => x.borrow().write_le(out),
680 #[cfg(feature = "i16")]
681 Value::I16(x) => x.borrow().write_le(out),
682 #[cfg(feature = "i32")]
683 Value::I32(x) => x.borrow().write_le(out),
684 #[cfg(feature = "i64")]
685 Value::I64(x) => x.borrow().write_le(out),
686 #[cfg(feature = "i128")]
687 Value::I128(x) => x.borrow().write_le(out),
688 #[cfg(feature = "f32")]
689 Value::F32(x) => x.borrow().write_le(out),
690 #[cfg(feature = "f64")]
691 Value::F64(x) => x.borrow().write_le(out),
692 #[cfg(feature = "rational")]
693 Value::R64(x) => x.borrow().write_le(out),
694 #[cfg(feature = "complex")]
695 Value::C64(x) => x.borrow().write_le(out),
696 _ => todo!(),
697 }
698 }
699 fn value_kind() -> ValueKind {ValueKind::Any}
700 fn align() -> u8 { 1 }
701}
702
703impl ConstElem for ValueKind {
704 fn write_le(&self, out: &mut Vec<u8>) {
705 match self {
706 ValueKind::U8 => out.write_u8(1).expect("write value kind"),
707 ValueKind::U16 => out.write_u8(2).expect("write value kind"),
708 ValueKind::U32 => out.write_u8(3).expect("write value kind"),
709 ValueKind::U64 => out.write_u8(4).expect("write value kind"),
710 ValueKind::U128 => out.write_u8(5).expect("write value kind"),
711 ValueKind::I8 => out.write_u8(6).expect("write value kind"),
712 ValueKind::I16 => out.write_u8(7).expect("write value kind"),
713 ValueKind::I32 => out.write_u8(8).expect("write value kind"),
714 ValueKind::I64 => out.write_u8(9).expect("write value kind"),
715 ValueKind::I128 => out.write_u8(10).expect("write value kind"),
716 ValueKind::F32 => out.write_u8(11).expect("write value kind"),
717 ValueKind::F64 => out.write_u8(12).expect("write value kind"),
718 ValueKind::C64 => out.write_u8(13).expect("write value kind"),
719 ValueKind::R64 => out.write_u8(14).expect("write value kind"),
720 ValueKind::String => out.write_u8(15).expect("write value kind"),
721 ValueKind::Bool => out.write_u8(16).expect("write value kind"),
722 ValueKind::Id => out.write_u8(17).expect("write value kind"),
723 ValueKind::Index => out.write_u8(18).expect("write value kind"),
724 ValueKind::Empty => out.write_u8(19).expect("write value kind"),
725 ValueKind::Any => out.write_u8(20).expect("write value kind"),
726 ValueKind::Matrix(elem_vk, dims) => {
727 out.write_u8(21).expect("write value kind");
728 elem_vk.write_le(out);
729 out.write_u32::<LittleEndian>(dims.len() as u32).expect("write matrix dims length");
730 for d in dims.iter() {
731 out.write_u32::<LittleEndian>(*d as u32).expect("write matrix dim");
732 }
733 },
734 ValueKind::Enum(id) => {
735 out.write_u8(22).expect("write value kind");
736 out.write_u64::<LittleEndian>(*id).expect("write enum id");
737 },
738 ValueKind::Record(fields) => {
739 out.write_u8(23).expect("write value kind");
740 out.write_u32::<LittleEndian>(fields.len() as u32).expect("write record fields length");
741 for (name, vk) in fields.iter() {
742 name.write_le(out);
743 vk.write_le(out);
744 }
745 },
746 ValueKind::Map(key_vk, val_vk) => {
747 out.write_u8(24).expect("write value kind");
748 key_vk.write_le(out);
749 val_vk.write_le(out);
750 },
751 ValueKind::Atom(id) => {
752 out.write_u8(25).expect("write value kind");
753 out.write_u64::<LittleEndian>(*id).expect("write atom id");
754 },
755 ValueKind::Table(fields, row_count) => {
756 out.write_u8(26).expect("write value kind");
757 out.write_u32::<LittleEndian>(fields.len() as u32).expect("write table fields length");
758 for (name, vk) in fields.iter() {
759 name.write_le(out);
760 vk.write_le(out);
761 }
762 out.write_u32::<LittleEndian>(*row_count as u32).expect("write table row count");
763 },
764 ValueKind::Tuple(vks) => {
765 out.write_u8(27).expect("write value kind");
766 out.write_u32::<LittleEndian>(vks.len() as u32).expect("write tuple length");
767 for vk in vks.iter() {
768 vk.write_le(out);
769 }
770 },
771 ValueKind::Reference(vk) => {
772 out.write_u8(28).expect("write value kind");
773 vk.write_le(out);
774 },
775 ValueKind::Set(vk, opt_size) => {
776 out.write_u8(29).expect("write value kind");
777 vk.write_le(out);
778 match opt_size {
779 Some(sz) => {
780 out.write_u8(1).expect("write set size flag");
781 out.write_u32::<LittleEndian>(*sz as u32).expect("write set size");
782 },
783 None => {
784 out.write_u8(0).expect("write set size flag");
785 }
786 }
787 },
788 ValueKind::Option(vk) => {
789 out.write_u8(30).expect("write value kind");
790 vk.write_le(out);
791 },
792 }
793 }
794 fn value_kind() -> ValueKind { ValueKind::Any }
795 fn align() -> u8 { 1 }
796}
797
798#[cfg(feature = "enum")]
799impl ConstElem for MechEnum {
800 fn write_le(&self, out: &mut Vec<u8>) {
801 out.write_u64::<LittleEndian>(self.id).expect("write enum id");
803
804 out.write_u32::<LittleEndian>(self.variants.len() as u32).expect("write enum variants length");
806
807 for (variant_id, variant_value) in self.variants.iter() {
809 out.write_u64::<LittleEndian>(*variant_id).expect("write enum variant id");
811 match variant_value {
812 Some(v) => {
813 out.write_u8(1).expect("write enum variant has value");
815 let value_kind = v.kind();
817 value_kind.write_le(out);
818 v.write_le(out);
820 },
821 None => {
822 out.write_u8(0).expect("write enum variant has no value");
824 }
825 }
826 }
827 }
828 fn value_kind() -> ValueKind { ValueKind::Enum(0) } fn align() -> u8 { 8 }
830}