#[allow(unused_imports)] use crate::{TelemetryError, VariableInfo, VariableSchema};
#[allow(unused_imports)] use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct AdapterValidation {
pub extraction_plan: Vec<FieldExtraction>,
index_map: HashMap<String, usize>,
}
impl AdapterValidation {
pub fn new(extraction_plan: Vec<FieldExtraction>) -> Self {
let index_map = extraction_plan
.iter()
.enumerate()
.filter_map(|(index, extraction)| {
extraction.field_name().map(|name| (name.to_string(), index))
})
.collect();
Self { extraction_plan, index_map }
}
pub fn field_count(&self) -> usize {
self.extraction_plan.len()
}
pub fn has_required_fields(&self) -> bool {
self.extraction_plan.iter().any(|field| matches!(field, FieldExtraction::Required { .. }))
}
pub fn index_of(&self, name: &str) -> Option<usize> {
self.index_map.get(name).copied()
}
pub fn fetch_or_default<T>(&self, packet: &crate::types::FramePacket, name: &str) -> T
where
T: crate::VarData + ::core::default::Default,
{
let data = packet.data.as_ref();
if let Some(index) = self.index_of(name) {
if let Some(entry) = self.extraction_plan.get(index) {
if let Some(var_info) = entry.var_info() {
if let Ok(value) = <T as crate::VarData>::from_bytes(data, var_info) {
return value;
}
}
}
}
if let Some(var_info) = packet.schema.get_variable(name) {
if let Ok(value) = <T as crate::VarData>::from_bytes(data, var_info) {
return value;
}
}
T::default()
}
}
#[derive(Debug, Clone)]
pub enum FieldExtraction {
Required {
name: String,
var_info: VariableInfo,
},
Optional {
name: String,
var_info: Option<VariableInfo>,
},
WithDefault {
name: String,
var_info: Option<VariableInfo>,
default_value: DefaultValue,
},
Calculated {
expression: String,
},
Skipped,
}
impl FieldExtraction {
pub fn field_name(&self) -> Option<&str> {
match self {
FieldExtraction::Required { name, .. }
| FieldExtraction::Optional { name, .. }
| FieldExtraction::WithDefault { name, .. } => Some(name),
FieldExtraction::Calculated { .. } | FieldExtraction::Skipped => None,
}
}
pub fn is_required(&self) -> bool {
matches!(self, FieldExtraction::Required { .. })
}
pub fn var_info(&self) -> Option<&VariableInfo> {
match self {
FieldExtraction::Required { var_info, .. } => Some(var_info),
FieldExtraction::Optional { var_info, .. }
| FieldExtraction::WithDefault { var_info, .. } => var_info.as_ref(),
FieldExtraction::Calculated { .. } | FieldExtraction::Skipped => None,
}
}
}
#[derive(Debug, Clone)]
pub enum DefaultValue {
TypeDefault,
ExplicitExpression(String),
}
impl DefaultValue {
pub fn describe(&self) -> &'static str {
match self {
DefaultValue::TypeDefault => "type default",
DefaultValue::ExplicitExpression(_) => "explicit expression",
}
}
}