use super::model::{AttributeData, TelemetryData};
use crate::{DataPointType, NorthwardData, PointValue};
use chrono::Utc;
use std::collections::HashMap;
#[derive(Debug, Default)]
pub struct DeviceBuffers {
device_name: String,
telemetry: Vec<PointValue>,
attributes: Vec<PointValue>,
}
impl DeviceBuffers {
#[inline]
pub fn new(device_name: impl Into<String>) -> Self {
Self {
device_name: device_name.into(),
telemetry: Vec::new(),
attributes: Vec::new(),
}
}
#[inline]
pub fn push(&mut self, kind: DataPointType, value: PointValue) {
match kind {
DataPointType::Telemetry => self.telemetry.push(value),
DataPointType::Attribute => self.attributes.push(value),
}
}
#[inline]
pub fn is_empty(&self) -> bool {
self.telemetry.is_empty() && self.attributes.is_empty()
}
#[inline]
pub fn into_northward(
self,
device_id: i32,
timestamp: chrono::DateTime<Utc>,
) -> Vec<NorthwardData> {
let DeviceBuffers {
device_name,
telemetry,
attributes,
} = self;
let has_telemetry = !telemetry.is_empty();
let has_attributes = !attributes.is_empty();
if !has_telemetry && !has_attributes {
return Vec::new();
}
let mut out = Vec::with_capacity((has_telemetry as usize) + (has_attributes as usize));
match (has_telemetry, has_attributes) {
(true, true) => {
out.push(NorthwardData::Telemetry(TelemetryData {
device_id,
device_name: device_name.clone(),
timestamp,
values: telemetry,
metadata: HashMap::new(),
}));
out.push(NorthwardData::Attributes(AttributeData {
device_id,
device_name,
timestamp,
client_attributes: attributes,
shared_attributes: Vec::new(),
server_attributes: Vec::new(),
}));
}
(true, false) => {
out.push(NorthwardData::Telemetry(TelemetryData {
device_id,
device_name,
timestamp,
values: telemetry,
metadata: HashMap::new(),
}));
}
(false, true) => {
out.push(NorthwardData::Attributes(AttributeData {
device_id,
device_name,
timestamp,
client_attributes: attributes,
shared_attributes: Vec::new(),
server_attributes: Vec::new(),
}));
}
(false, false) => {}
}
out
}
}