use serde::{de, Deserialize, Deserializer, Serialize};
use custom_error::custom_error;
use serde_json::{Map, Value};
use strum_macros::{AsRefStr, EnumString};
use super::{structures::{AttributeRule, ConstraintRule}, traits::Describe};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "lowercase", deny_unknown_fields)]
pub enum Uap {
Uap { items: Vec<String> },
}
#[derive(Clone)]
pub enum AttributeConstraintLimit {
SignedInteger { value: i32 },
}
#[derive(AsRefStr, EnumString, Clone)]
pub enum AttributeLsb {
Integer { value: i32 },
Real { value: f64 }
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum DataType {
Integer { value: i32 },
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
pub enum ConstraintType {
#[serde(rename = "<")]
Less,
#[serde(rename = ">")]
Great,
#[serde(rename = "<=")]
LessOrEqual,
#[serde(rename = ">=")]
GreatOrEqual,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum DenominatorType {
Pow {
base: f64,
exponent: f64,
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum LsbType {
Integer {
value: i32
},
Div {
denominator: DenominatorType,
numerator: DataType
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum ElementValueType {
Fx,
Integer {
constraints: Vec<ConstraintRule>,
signed: bool,
},
Quantity {
constraints: Vec<ConstraintRule>,
lsb: LsbType,
signed: bool,
unit: String
},
Raw,
Regular {size: u8},
String { variation: String },
Table {
values: Vec<(i32, String)>
},
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum DataRecordType {
Basic,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum ElementType {
ContextFree {
value: ElementValueType
}
}
impl Default for ElementType {
fn default() -> Self {
ElementType::ContextFree { value: ElementValueType::default() }
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum DataItemValueType {
Element {
rule: ElementType,
size: u8,
},
Group {
items: Vec<Option<AttributeItem>>,
},
Extended {
items: Vec<Option<AttributeItem>>,
},
Repetitive {
rep: ElementValueType,
variation: Box<AttributeValueType>
},
Compound {
fspec: Option<u8>,
items: Vec<Option<AttributeItem>>,
},
Explicit {
expl: String
}
}
impl Describe for DataItemValueType {
fn describe(&self, indent_level: &mut usize) -> String {
self.get_indented_description(indent_level, String::from("This should not being saw!, from DataItemValueType describe method"))
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum DataItemType {
ContextFree {
value: DataItemValueType
},
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum AttributeType {
ContextFree {
value: AttributeValueType
},
}
custom_error!{pub Deserialization
DeserializationError{attribute: String, error: String} = "Error deserializing definition of attribute {attribute}, error:{error}",
}
#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(untagged, deny_unknown_fields)]
pub enum AttributeItem {
SpareEntry { length: usize, spare: bool },
AttributeEntry(AttributeRule),
}
impl<'de> Deserialize<'de> for AttributeItem {
fn deserialize<D>(deserializer: D) -> anyhow::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let map = Map::deserialize(deserializer)?;
let spare: bool;
let mut spare_length = 0;
let has_spare = match map.get("spare") {
Some(v) => {
spare = serde_json::from_value(v.clone()).unwrap_or(false);
spare != false
}
None => false
};
if has_spare {
match map.get("length") {
Some(v) => {
spare_length = serde_json::from_value(v.clone()).unwrap_or(0);
}
None => Err(Deserialization::DeserializationError {
attribute: "AttributeItem::SpareEntry".to_owned(),
error: "could not find spare length".to_owned() })
.map_err(de::Error::custom)?
}
}
if has_spare {
Ok(AttributeItem::SpareEntry { length: spare_length, spare: has_spare })
} else {
let rest = Value::Object(map);
let attribute_type = AttributeRule::deserialize(rest).unwrap_or_default();
let attribute_item = AttributeItem::AttributeEntry(attribute_type);
Ok(attribute_item)
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum AttributeValueType {
Element {
rule: ElementType,
size: u8,
},
Group {
items: Vec<Option<AttributeItem>>,
},
Repetitive {
rep: ElementValueType,
variation: Box<AttributeValueType>
},
Table {
values: Vec<(i32, String)>
}
}
impl Default for ElementValueType {
fn default() -> Self {
ElementValueType::Raw
}
}
impl Default for AttributeValueType {
fn default() -> Self {
AttributeValueType::Element { rule: ElementType::default(), size: 8 }
}
}
impl Default for AttributeType {
fn default() -> Self {
AttributeType::ContextFree { value: AttributeValueType::default() }
}
}