use std::collections::BTreeMap;
use bitvec::prelude::*;
use serde::{Deserialize, Serialize};
use super::traits::Describe;
use super::enums::{AttributeConstraintLimit, AttributeLsb, AttributeType, ConstraintType, DataItemType, DataRecordType, DataType, Uap};
#[derive(Default, Clone)]
pub struct FSpecInfo {
pub len: u8,
pub fspec:BTreeMap<u8, bool>
}
#[derive(Clone)]
pub struct AttributeConstraint {
pub constraint_type: ConstraintType,
pub limit_value: AttributeConstraintLimit
}
#[derive(Default, Clone) ]
pub struct Attribute {
pub name: String,
pub title: String,
pub bits: BitVec<u8, Msb0>,
pub value_type: String,
pub stringfied_value: Option<String>,
pub signed: Option<bool>,
pub constraints: Option<Vec<AttributeConstraint>>,
pub lsb: Option<AttributeLsb>,
pub unit: Option<String>,
pub description: Option<String>
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Date {
pub day: u8,
pub month: u8,
pub year: u16,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Hash)]
#[serde(deny_unknown_fields)]
pub struct Edition {
pub major: u32,
pub minor: u32,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct DataRecord {
pub catalogue: Vec<DataItemRule>,
pub date: Date,
pub edition: Edition,
pub number: u8,
pub preamble: String,
pub title: String,
#[serde(rename = "type")]
pub type_value: DataRecordType,
pub uap: Uap,
}
impl Describe for DataRecord {
fn describe(&self, indent_level: &mut usize) -> String {
let self_description = format!("Category: {:03}, {}, edition: {}.{}",
self.number,
self.title,
self.edition.major,
self.edition.minor);
let mut description = vec![self.get_indented_description(indent_level, self_description)];
for dataitem in &self.catalogue {
description.push(dataitem.describe(indent_level));
}
description.join("\n")
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct DataItemRule {
pub definition: Option<String>,
pub description: Option<String>,
pub name: String,
pub remark: Option<String>,
pub rule: DataItemType,
pub spare: bool,
pub title: String,
}
impl Describe for DataItemRule {
fn describe(&self, indent_level: &mut usize) -> String {
let self_description = format!("DataItem: {:03}, {}, spare: {}",
self.name,
self.title,
if self.spare { "true" } else {"false"});
let mut description = vec![self.get_indented_description(indent_level, self_description)];
let rule_desc: String;
rule_desc = match &self.rule {
DataItemType::ContextFree { value } => value.describe(indent_level),
};
description.push(rule_desc);
description.join("\n")
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ConstraintRule {
#[serde(rename = "type")]
pub constraint_type: ConstraintType,
pub value: DataType,
}
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
pub struct AttributeRule {
pub definition: Option<String>,
pub description: Option<String>,
pub name: String,
pub remark: Option<String>,
pub rule: AttributeType,
pub spare: bool,
pub title: String,
}
impl Describe for AttributeRule {
fn describe(&self, indent: &mut usize) -> String {
self.get_indented_description(indent, format!("Attribute rule: {}, {}", self.name, self.title))
}
}