use chrono::{DateTime, Duration, Utc};
use serde::{Deserialize, Serialize};
use crate::serde::{
duration_milliseconds_string_option, ts_milliseconds_string, ts_milliseconds_string_option,
};
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct LongTermTimingProperties {
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "duration_milliseconds_string_option"
)]
local_initial_timediff: Option<Duration>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "ts_milliseconds_string_option"
)]
initial_timestamp: Option<DateTime<Utc>>,
#[serde(with = "ts_milliseconds_string")]
broker_timestamp: DateTime<Utc>,
#[serde(with = "ts_milliseconds_string")]
broker_processing_timestamp: DateTime<Utc>,
#[serde(with = "ts_milliseconds_string")]
broker_initial_processing_timestamp: DateTime<Utc>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "duration_milliseconds_string_option"
)]
cumulative_authorization_time: Option<Duration>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "duration_milliseconds_string_option"
)]
cumulative_processing_time: Option<Duration>,
}
impl LongTermTimingProperties {
pub fn update_cumulative_timings(
self,
short_timing: &OutgoingShortTermTimingProperties,
) -> Self {
let cumulative_authorization_time = short_timing
.authorization_time
.map(|increment| {
self.cumulative_authorization_time
.map_or(increment, |initial| initial + increment)
})
.or(self.cumulative_authorization_time);
let cumulative_processing_time = short_timing
.processing_time
.map(|increment| {
self.cumulative_processing_time
.map_or(increment, |initial| initial + increment)
})
.or(self.cumulative_processing_time);
Self {
cumulative_authorization_time,
cumulative_processing_time,
..self
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct OutgoingShortTermTimingProperties {
#[serde(with = "ts_milliseconds_string")]
timestamp: DateTime<Utc>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "duration_milliseconds_string_option"
)]
processing_time: Option<Duration>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "duration_milliseconds_string_option"
)]
authorization_time: Option<Duration>,
}
impl OutgoingShortTermTimingProperties {
pub fn until_now(start_timestamp: DateTime<Utc>) -> Self {
let now = Utc::now();
let mut timing = Self::new(now);
timing.set_processing_time(now - start_timestamp);
timing
}
pub fn new(timestamp: DateTime<Utc>) -> Self {
Self {
timestamp,
processing_time: None,
authorization_time: None,
}
}
pub fn set_processing_time(&mut self, processing_time: Duration) -> &mut Self {
self.processing_time = Some(processing_time);
self
}
pub fn set_authorization_time(&mut self, authorization_time: Duration) -> &mut Self {
self.authorization_time = Some(authorization_time);
self
}
}
pub type ShortTermTimingProperties = OutgoingShortTermTimingProperties;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct IncomingShortTermTimingProperties {
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "ts_milliseconds_string_option"
)]
timestamp: Option<DateTime<Utc>>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "duration_milliseconds_string_option"
)]
processing_time: Option<Duration>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "duration_milliseconds_string_option"
)]
authorization_time: Option<Duration>,
}