1use std::fmt::Display;
2
3use serde::Deserialize;
4
5use super::{Omf1Error, objects::*};
6
7pub trait FromModel {
12 type Output<'a>;
13
14 fn from_model(model: &Model) -> Result<Self::Output<'_>, Omf1Error>;
15}
16
17macro_rules! model {
19 ($( $variant:ident )*) => {
20 #[derive(Debug, Deserialize)]
22 #[serde(tag = "__class__")]
23 pub enum Model {
24 $( $variant($variant), )*
25 }
26
27 #[derive(Debug)]
29 pub enum ModelType {
30 $( $variant, )*
31 }
32
33 impl Model {
34 fn model_type(&self) -> ModelType {
36 match self {
37 $( Self::$variant(_) => ModelType::$variant, )*
38 }
39 }
40 }
41
42 $(
43 impl FromModel for $variant {
44 type Output<'a> = &'a $variant;
45
46 fn from_model(model: &Model) -> Result<Self::Output<'_>, Omf1Error> {
47 match model {
48 Model::$variant(x) => Ok(x),
49 _ => Err(Omf1Error::WrongType {
50 found: model.model_type(),
51 expected: &[ModelType::$variant],
52 }),
53 }
54 }
55 }
56 )*
57 };
58}
59
60macro_rules! model_subset {
67 ($model_name:ident $enum_name:ident { $( $variant:ident )* }) => {
68 #[derive(Debug)]
69 pub struct $model_name {}
70
71 #[derive(Debug, Clone, Copy)]
72 #[allow(clippy::enum_variant_names)]
73 pub enum $enum_name<'a> {
74 $( $variant(&'a $variant), )*
75 }
76
77 impl FromModel for $model_name {
78 type Output<'a> = $enum_name<'a>;
79
80 fn from_model(model: &Model) -> Result<Self::Output<'_>, Omf1Error> {
81 match model {
82 $( Model::$variant(x) => Ok($enum_name::$variant(x)), )*
83 _ => Err(Omf1Error::WrongType {
84 found: model.model_type(),
85 expected: &[$( ModelType::$variant ),*],
86 }),
87 }
88 }
89 }
90 };
91}
92
93model! {
94 Project
95 PointSetElement
96 PointSetGeometry
97 LineSetElement
98 LineSetGeometry
99 SurfaceElement
100 SurfaceGeometry
101 SurfaceGridGeometry
102 VolumeElement
103 VolumeGridGeometry
104 ScalarColormap
105 DateTimeColormap
106 Legend
107 ScalarData
108 DateTimeData
109 Vector2Data
110 Vector3Data
111 ColorData
112 StringData
113 MappedData
114 ImageTexture
115 ScalarArray
116 Vector2Array
117 Vector3Array
118 Int2Array
119 Int3Array
120 StringArray
121 DateTimeArray
122 ColorArray
123}
124
125impl Display for ModelType {
126 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127 write!(f, "{self:?}")
128 }
129}
130
131model_subset! {
132 Elements ElementModel {
133 PointSetElement
134 LineSetElement
135 SurfaceElement
136 VolumeElement
137 }
138}
139
140model_subset! {
141 Data DataModel {
142 ScalarData
143 DateTimeData
144 Vector2Data
145 Vector3Data
146 ColorData
147 StringData
148 MappedData
149 }
150}
151
152model_subset! {
153 SurfaceGeometries SurfaceGeometryModel {
154 SurfaceGeometry
155 SurfaceGridGeometry
156 }
157}
158
159model_subset! {
160 LegendArrays LegendArrayModel {
161 ColorArray
162 DateTimeArray
163 StringArray
164 ScalarArray
165 }
166}
167
168model_subset! {
169 ColorArrays ColorArrayModel {
170 Int3Array
171 ColorArray
172 }
173}