use anyhow::bail;
use chrono::{DateTime, NaiveDateTime, TimeDelta, Utc};
use serde::{Deserialize, Serialize};
use tokio_postgres::Row;
#[derive(Serialize, Deserialize, Debug)]
pub struct TrendDataRaw {
pub externallogid: i64,
pub timestamp: String,
pub timestamp_tzinfo: i64,
pub value: Option<f64>,
}
#[derive(Debug, Clone)]
pub struct TrendDataDb {
pub log_id: i64,
pub timestamp: DateTime<Utc>,
pub value: Option<f64>
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct MetadataJson {
pub externallogid: i64,
pub source: String,
pub unit: String,
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct MetadataDb {
pub log_id: i64,
pub source: String,
pub unit: String,
}
impl From<&Row> for MetadataDb {
fn from(value: &Row) -> MetadataDb {
let log_id: i64 = value.get("log_id");
let source: String = value.get("source");
let unit: String = value.get("unit");
MetadataDb { log_id, source, unit }
}
}
impl TryFrom<&TrendDataRaw> for TrendDataDb {
type Error = anyhow::Error;
fn try_from(value: &TrendDataRaw) -> Result<Self, Self::Error> {
let naive_timestamp = NaiveDateTime::parse_from_str(&value.timestamp, "%Y-%m-%d %H:%M:%S");
if let Err(e) = naive_timestamp {
let timestamp = &value.timestamp;
bail!("error parsing {timestamp}: {e}");
}
let mut naive_timestamp = naive_timestamp.unwrap();
match value.timestamp_tzinfo {
248 => { naive_timestamp = naive_timestamp - TimeDelta::hours(1);
},
241 => { naive_timestamp = naive_timestamp - TimeDelta::hours(2);
},
_ => {
let timezone = value.timestamp_tzinfo;
bail!("did not recognize timestamp timezone {timezone}");
}
}
let utc_time: DateTime<Utc> = naive_timestamp.and_local_timezone(Utc).unwrap();
Ok(TrendDataDb {
log_id: value.externallogid,
timestamp: utc_time,
value: value.value,
})
}
}
impl From<&Row> for TrendDataDb {
fn from(row: &Row) -> TrendDataDb {
let log_id: i64 = row.get("log_id");
let timestamp: DateTime<Utc> = row.get("timestamp");
let value: Option<f64> = row.get("value");
TrendDataDb {
log_id,
timestamp,
value
}
}
}