use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Database {
pub telemetries: Vec<Telemetry>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Telemetry {
pub name: String,
pub metadata: Metadata,
#[serde(rename = "entries")]
pub content: Content,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Metadata {
pub target: String,
pub packet_id: u8,
pub is_enabled: bool,
pub is_restricted: bool,
pub local_variables: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Content {
Blob,
Struct(Vec<Entry>),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE", tag = "type")]
pub enum Entry {
FieldGroup(FieldGroup),
Comment(Comment),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct FieldGroup {
pub onboard_software_info: OnboardSoftwareInfo,
pub sub_entries: Vec<SubEntry>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE", tag = "type")]
#[allow(clippy::large_enum_variant)]
pub enum SubEntry {
Field(Field),
Comment(Comment),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Field {
pub name: String,
pub extraction_info: FieldExtractionInfo,
pub conversion_info: ConversionInfo,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")] pub display_info: Option<DisplayInfo>,
pub description: String,
pub note: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct FieldExtractionInfo {
pub extraction_type: String,
pub octet_position: usize,
pub bit_position: usize,
pub bit_length: usize,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct OnboardSoftwareInfo {
pub variable_type: VariableType,
pub expression: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ConversionInfo {
None,
Hex,
Status(conversion::Status),
Polynomial(conversion::Polynomial),
}
pub mod conversion {
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Status {
pub variants: Vec<Variant>,
pub default_value: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Variant {
pub key: i64,
pub value: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Polynomial {
pub a0: f64,
pub a1: f64,
pub a2: f64,
pub a3: f64,
pub a4: f64,
pub a5: f64,
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum VariableType {
#[serde(rename = "int8_t")]
Int8,
#[serde(rename = "int16_t")]
Int16,
#[serde(rename = "int32_t")]
Int32,
#[serde(rename = "uint8_t")]
Uint8,
#[serde(rename = "uint16_t")]
Uint16,
#[serde(rename = "uint32_t")]
Uint32,
#[serde(rename = "float")]
Float,
#[serde(rename = "double")]
Double,
}
impl VariableType {
pub fn octet_width(&self) -> usize {
match self {
VariableType::Int8 => 1,
VariableType::Int16 => 2,
VariableType::Int32 => 4,
VariableType::Uint8 => 1,
VariableType::Uint16 => 2,
VariableType::Uint32 => 4,
VariableType::Float => 4,
VariableType::Double => 8,
}
}
pub fn bit_width(&self) -> usize {
self.octet_width() * 8
}
pub fn is_unsigned_integer(&self) -> bool {
matches!(
self,
VariableType::Uint8 | VariableType::Uint16 | VariableType::Uint32
)
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct DisplayInfo {
pub label: String,
pub unit: String,
pub format: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Comment {
pub text: String,
}