use std::fmt::Display;
use serde::Deserialize;
use super::{objects::*, Omf1Error};
pub trait FromModel {
type Output<'a>;
fn from_model(model: &Model) -> Result<Self::Output<'_>, Omf1Error>;
}
macro_rules! model {
($( $variant:ident )*) => {
#[derive(Debug, Deserialize)]
#[serde(tag = "__class__")]
pub enum Model {
$( $variant($variant), )*
}
#[derive(Debug)]
pub enum ModelType {
$( $variant, )*
}
impl Model {
fn model_type(&self) -> ModelType {
match self {
$( Self::$variant(_) => ModelType::$variant, )*
}
}
}
$(
impl FromModel for $variant {
type Output<'a> = &'a $variant;
fn from_model(model: &Model) -> Result<Self::Output<'_>, Omf1Error> {
match model {
Model::$variant(x) => Ok(x),
_ => Err(Omf1Error::WrongType {
found: model.model_type(),
expected: &[ModelType::$variant],
}),
}
}
}
)*
};
}
macro_rules! model_subset {
($model_name:ident $enum_name:ident { $( $variant:ident )* }) => {
#[derive(Debug)]
pub struct $model_name {}
#[derive(Debug, Clone, Copy)]
#[allow(clippy::enum_variant_names)]
pub enum $enum_name<'a> {
$( $variant(&'a $variant), )*
}
impl FromModel for $model_name {
type Output<'a> = $enum_name<'a>;
fn from_model(model: &Model) -> Result<Self::Output<'_>, Omf1Error> {
match model {
$( Model::$variant(x) => Ok($enum_name::$variant(x)), )*
_ => Err(Omf1Error::WrongType {
found: model.model_type(),
expected: &[$( ModelType::$variant ),*],
}),
}
}
}
};
}
model! {
Project
PointSetElement
PointSetGeometry
LineSetElement
LineSetGeometry
SurfaceElement
SurfaceGeometry
SurfaceGridGeometry
VolumeElement
VolumeGridGeometry
ScalarColormap
DateTimeColormap
Legend
ScalarData
DateTimeData
Vector2Data
Vector3Data
ColorData
StringData
MappedData
ImageTexture
ScalarArray
Vector2Array
Vector3Array
Int2Array
Int3Array
StringArray
DateTimeArray
ColorArray
}
impl Display for ModelType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{self:?}")
}
}
model_subset! {
Elements ElementModel {
PointSetElement
LineSetElement
SurfaceElement
VolumeElement
}
}
model_subset! {
Data DataModel {
ScalarData
DateTimeData
Vector2Data
Vector3Data
ColorData
StringData
MappedData
}
}
model_subset! {
SurfaceGeometries SurfaceGeometryModel {
SurfaceGeometry
SurfaceGridGeometry
}
}
model_subset! {
LegendArrays LegendArrayModel {
ColorArray
DateTimeArray
StringArray
ScalarArray
}
}
model_subset! {
ColorArrays ColorArrayModel {
Int3Array
ColorArray
}
}