use_prelude!();
use chrono::{DateTime, Utc};
use crate::error::{DittoError, ErrorKind};
pub struct TimeSeries {
pub(super) ditto: Arc<ffi_sdk::BoxedDitto>,
pub(super) ts_name: char_p::Box,
}
impl TimeSeries {
pub fn insert<T: ::serde::Serialize>(
&self,
datetime: &DateTime<Utc>,
content: T,
) -> Result<(), DittoError> {
let cbor = ::serde_cbor::to_vec(content.borrow())?;
let ditto_time = DittoTimestamp::from(datetime);
let status = {
ffi_sdk::ditto_insert_timeseries_event(
&*self.ditto,
ditto_time.epoch_bytes(),
ditto_time.nanoseconds(),
self.ts_name.as_ref(),
cbor.as_slice().into(),
None,
)
};
if status != 0 {
Err(DittoError::from_ffi(ErrorKind::InvalidInput))
} else {
Ok(())
}
}
}
#[derive(Debug)]
pub struct DittoTimestamp {
pub epoch_sec: u64,
pub nanos: u32,
}
impl DittoTimestamp {
pub(crate) fn new(epoch_sec: u64, nanos: u32) -> Self {
DittoTimestamp { epoch_sec, nanos }
}
pub fn utc_now() -> Self {
let datetime = Utc::now();
let epoch_sec: u64 = datetime.timestamp() as u64;
let nanos: u32 = datetime.timestamp_subsec_nanos();
Self::new(epoch_sec, nanos)
}
pub fn epoch_bytes(&self) -> [u8; 8] {
self.epoch_sec.to_be_bytes()
}
pub fn nanoseconds(&self) -> u32 {
self.nanos
}
}
impl From<&::chrono::DateTime<Utc>> for DittoTimestamp {
fn from(datetime: &::chrono::DateTime<Utc>) -> DittoTimestamp {
let epoch_sec: u64 = datetime.timestamp() as u64;
let nanos: u32 = datetime.timestamp_subsec_nanos();
DittoTimestamp::new(epoch_sec, nanos)
}
}