use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use super::VariableType;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tauri", derive(specta::Type))]
pub struct VariableSchema {
pub variables: HashMap<String, VariableInfo>,
pub frame_size: usize,
}
impl VariableSchema {
pub fn new(variables: HashMap<String, VariableInfo>, frame_size: usize) -> crate::Result<Self> {
let schema = Self { variables, frame_size };
schema.validate()?;
Ok(schema)
}
pub fn validate(&self) -> crate::Result<()> {
for (name, var_info) in &self.variables {
if var_info.count == 0 {
return Err(crate::TelemetryError::Parse {
context: "Schema validation".to_string(),
details: format!("Variable '{}' has count of 0", name),
});
}
if var_info.name != *name {
return Err(crate::TelemetryError::Parse {
context: "Schema validation".to_string(),
details: format!(
"Variable map key '{}' doesn't match info name '{}'",
name, var_info.name
),
});
}
let end_offset = var_info.offset + (var_info.data_type.size() * var_info.count);
if end_offset > self.frame_size {
return Err(crate::TelemetryError::Memory {
offset: var_info.offset,
source: None,
});
}
}
Ok(())
}
pub fn get_variable(&self, name: &str) -> Option<&VariableInfo> {
self.variables.get(name)
}
pub fn has_variable(&self, name: &str) -> bool {
self.variables.contains_key(name)
}
pub fn variable_count(&self) -> usize {
self.variables.len()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tauri", derive(specta::Type))]
pub struct VariableInfo {
pub name: String,
pub data_type: VariableType,
pub offset: usize,
pub count: usize,
pub count_as_time: bool,
pub units: String,
pub description: String,
}