use std::collections::HashMap;
use chrono::{DateTime, Utc};
use relay_common::time::UnixTimestamp;
use serde::{Deserialize, Serialize};
use crate::MetricResourceIdentifier;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct MetricMeta {
pub timestamp: StartOfDayUnixTimestamp,
pub mapping: HashMap<MetricResourceIdentifier<'static>, Vec<Item>>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum Item {
Location(Location),
#[serde(other)]
Unknown,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct Location {
#[serde(skip_serializing_if = "Option::is_none")]
pub filename: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub abs_path: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub module: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub function: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lineno: Option<u64>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub pre_context: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub context_line: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub post_context: Vec<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StartOfDayUnixTimestamp(UnixTimestamp);
impl StartOfDayUnixTimestamp {
pub fn new(ts: UnixTimestamp) -> Option<Self> {
let dt: DateTime<Utc> = DateTime::from_timestamp(ts.as_secs().try_into().ok()?, 0)?;
let beginning_of_day = dt.date_naive().and_hms_opt(0, 0, 0)?.and_utc();
Some(Self(UnixTimestamp::from_datetime(beginning_of_day)?))
}
pub fn as_timestamp(&self) -> UnixTimestamp {
self.0
}
}
impl std::ops::Deref for StartOfDayUnixTimestamp {
type Target = UnixTimestamp;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Serialize for StartOfDayUnixTimestamp {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.0.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for StartOfDayUnixTimestamp {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let ts = UnixTimestamp::deserialize(deserializer)?;
StartOfDayUnixTimestamp::new(ts)
.ok_or_else(|| serde::de::Error::custom("invalid timestamp"))
}
}