mod datatype;
pub use datatype::DataType;
use std::collections::HashMap;
use tracing::error;
#[derive(Debug)]
pub struct Sensor {
#[allow(dead_code)]
pub(crate) name: String,
#[allow(dead_code)]
pub(crate) s_id: i64,
}
#[derive(Debug, Clone)]
pub struct Metric {
pub name: String,
pub value: String,
pub time: f64,
}
impl From<Metric> for fsipc::legacy::Measure {
fn from(f: Metric) -> Self {
#[allow(
clippy::cast_sign_loss,
clippy::cast_possible_wrap,
clippy::cast_possible_truncation
)]
let timestamp = f.time as u64;
Self {
key: f.name,
value: f.value,
timestamp,
}
}
}
impl From<fsipc::legacy::Measure> for Metric {
fn from(f: fsipc::legacy::Measure) -> Self {
#[allow(
clippy::cast_sign_loss,
clippy::cast_possible_wrap,
clippy::cast_precision_loss
)]
let time = f.timestamp as f64;
Self {
name: f.key,
value: f.value,
time,
}
}
}
#[derive(Debug)]
pub struct TXMetric {
pub(crate) id: i64,
pub(crate) name: String,
pub(crate) value: String,
pub(crate) time: i64,
}
impl From<TXMetric> for fsipc::legacy::PreparedPoint {
fn from(f: TXMetric) -> Self {
#[allow(clippy::cast_sign_loss)]
Self {
id: f.id,
key: f.name,
value: f.value,
timestamp: f.time as u64,
}
}
}
#[derive(Debug)]
pub struct Transaction {
pub(crate) name: String,
pub(crate) expected: String,
pub(crate) target: String,
pub(crate) t_id: i64,
#[allow(dead_code)]
pub(crate) status: String,
}
impl From<Transaction> for fsipc::legacy::Transaction {
fn from(f: Transaction) -> Self {
#[allow(clippy::cast_sign_loss, clippy::cast_possible_wrap)]
Self {
key: f.name,
expected: f.expected,
target: f.target,
t_id: f.t_id as u64,
}
}
}
pub type ValueMap = HashMap<u32, String>;
#[derive(Debug, Eq, PartialEq)]
pub enum SensorMode {
ReadOnly,
ReadWrite,
WriteOnly,
}
impl SensorMode {
#[must_use]
pub const fn as_str(&self) -> &str {
match self {
Self::ReadOnly => "ro",
Self::ReadWrite => "rw",
Self::WriteOnly => "wo",
}
}
#[must_use]
pub fn maybe_from_str(value: &str) -> Option<Self> {
match value {
"ro" => Some(Self::ReadOnly),
"rw" => Some(Self::ReadWrite),
"wo" => Some(Self::WriteOnly),
_ => None,
}
}
}
impl From<fsipc::logger1::SensorMode> for SensorMode {
fn from(other: fsipc::logger1::SensorMode) -> Self {
match other {
fsipc::logger1::SensorMode::ReadOnly => Self::ReadOnly,
fsipc::logger1::SensorMode::ReadWrite => Self::ReadWrite,
fsipc::logger1::SensorMode::WriteOnly => Self::WriteOnly,
}
}
}
#[allow(clippy::from_over_into)]
impl Into<fsipc::logger1::SensorMode> for SensorMode {
fn into(self) -> fsipc::logger1::SensorMode {
match self {
Self::ReadOnly => fsipc::logger1::SensorMode::ReadOnly,
Self::ReadWrite => fsipc::logger1::SensorMode::ReadWrite,
Self::WriteOnly => fsipc::logger1::SensorMode::WriteOnly,
}
}
}
#[test]
fn enum_roundtrip() {
fn around(b: &SensorMode) -> SensorMode {
let sval = b.as_str();
SensorMode::maybe_from_str(sval).unwrap()
}
assert_eq!(SensorMode::ReadOnly, around(&SensorMode::ReadOnly));
assert_eq!(SensorMode::ReadWrite, around(&SensorMode::ReadWrite));
assert_eq!(SensorMode::WriteOnly, around(&SensorMode::WriteOnly));
}
#[derive(Debug)]
pub struct Metadata {
pub n: String,
pub u: Option<String>,
pub name: Option<String>,
pub description: Option<String>,
pub value_map: Option<ValueMap>,
pub mode: Option<SensorMode>,
pub row: Option<Vec<DataType>>,
}
#[derive(Debug)]
pub struct MetadataBuilder {
n: String,
u: Option<String>,
name: Option<String>,
description: Option<String>,
value_map: Option<ValueMap>,
mode: Option<SensorMode>,
row: Option<Vec<DataType>>,
}
impl Metadata {
#[must_use]
pub fn builder(n: impl Into<String>) -> MetadataBuilder {
MetadataBuilder::new(n.into())
}
}
impl MetadataBuilder {
#[must_use]
pub const fn new(n: String) -> Self {
Self {
n,
u: None,
name: None,
description: None,
value_map: None,
mode: None,
row: None,
}
}
#[must_use]
pub fn name(mut self, name: String) -> Self {
self.name = Some(name);
self
}
#[must_use]
pub fn unit(mut self, u: String) -> Self {
self.u = Some(u);
self
}
#[must_use]
pub fn description(mut self, description: String) -> Self {
self.description = Some(description);
self
}
#[must_use]
pub fn value_map(mut self, value_map: ValueMap) -> Self {
self.value_map = Some(value_map);
self
}
#[must_use]
pub const fn mode(mut self, mode: SensorMode) -> Self {
self.mode = Some(mode);
self
}
#[must_use]
pub fn mode_string(mut self, value: &str) -> Self {
self.mode = SensorMode::maybe_from_str(value);
self
}
#[must_use]
pub fn value_map_string(mut self, value: String) -> Self {
let value_map = serde_json::from_str::<ValueMap>(&value);
if value_map.is_err() {
error!("Error decoding json: {:?}", value);
};
self.value_map = value_map.ok();
self
}
#[must_use]
pub fn row_string(mut self, value: &str) -> Self {
self.row = DataType::vec_from_str(value).ok();
self
}
#[must_use]
pub fn pair(self, tag: &str, value: String) -> Self {
match tag {
"unit" => self.unit(value),
"description" => self.description(value),
"name" => self.name(value),
"enum" => self.value_map_string(value),
"mode" => self.mode_string(&value),
"row" => self.row_string(&value),
_ => {
error!("Strange decoding pair? {:?} {:?}", tag, &value);
self
}
}
}
#[must_use]
pub fn build(self) -> Metadata {
let Self {
n,
u,
name,
description,
value_map,
mode,
row,
} = self;
Metadata {
n,
u,
name,
description,
value_map,
mode,
row,
}
}
}
#[derive(Debug, Default)]
pub struct CleanResult {
pub trans_failed: i32,
pub trans_old: i32,
pub data_deleted: i32,
}
impl std::fmt::Display for CleanResult {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"transactions_failed={}, transactions_old={}, data_deleted={}",
self.trans_failed, self.trans_old, self.data_deleted,
)
}
}
#[derive(Debug, Default)]
pub struct Statistics {
pub metrics: i32,
pub internal: i32,
pub removed: i32,
pub timefail: i32,
pub transactions: i32,
pub buffered: i32,
}
impl std::fmt::Display for Statistics {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"metrics={}, internal={}, removed={}, timefail={}, transactions={}, buffered={}",
self.metrics,
self.internal,
self.removed,
self.timefail,
self.transactions,
self.buffered
)
}
}