use serde::Deserialize;
#[derive(Debug, Default, Deserialize)]
#[serde(default)]
pub struct Resource {
pub attributes: Vec<KeyValue>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(default)]
pub struct KeyValue {
pub key: String,
pub value: AnyValue,
}
#[derive(Debug, Default, Deserialize)]
#[serde(default, rename_all = "camelCase")]
pub struct AnyValue {
pub string_value: Option<String>,
#[serde(deserialize_with = "deserialize_int_value", default)]
pub int_value: Option<String>,
pub double_value: Option<f64>,
pub bool_value: Option<bool>,
}
fn deserialize_int_value<'de, D>(deserializer: D) -> std::result::Result<Option<String>, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de;
struct IntOrString;
impl<'de> de::Visitor<'de> for IntOrString {
type Value = Option<String>;
fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.write_str("an integer or a string")
}
fn visit_i64<E: de::Error>(self, v: i64) -> std::result::Result<Self::Value, E> {
Ok(Some(v.to_string()))
}
fn visit_u64<E: de::Error>(self, v: u64) -> std::result::Result<Self::Value, E> {
Ok(Some(v.to_string()))
}
fn visit_str<E: de::Error>(self, v: &str) -> std::result::Result<Self::Value, E> {
Ok(Some(v.to_owned()))
}
fn visit_none<E: de::Error>(self) -> std::result::Result<Self::Value, E> {
Ok(None)
}
fn visit_unit<E: de::Error>(self) -> std::result::Result<Self::Value, E> {
Ok(None)
}
}
deserializer.deserialize_any(IntOrString)
}
impl AnyValue {
pub fn as_str(&self) -> Option<&str> {
self.string_value.as_deref()
}
pub fn as_i64(&self) -> Option<i64> {
self.int_value
.as_deref()
.and_then(|s| s.parse::<i64>().ok())
}
pub fn as_f64(&self) -> Option<f64> {
self.double_value
}
}
#[derive(Debug, Default, Deserialize)]
#[serde(default, rename_all = "camelCase")]
pub struct ExportMetricsRequest {
pub resource_metrics: Vec<ResourceMetric>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(default, rename_all = "camelCase")]
pub struct ResourceMetric {
pub resource: Resource,
pub scope_metrics: Vec<ScopeMetric>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(default, rename_all = "camelCase")]
pub struct ScopeMetric {
pub metrics: Vec<Metric>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(default)]
pub struct Metric {
pub name: String,
pub sum: Option<Sum>,
pub gauge: Option<Gauge>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(default, rename_all = "camelCase")]
pub struct Sum {
pub data_points: Vec<NumberDataPoint>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(default, rename_all = "camelCase")]
pub struct Gauge {
pub data_points: Vec<NumberDataPoint>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(default, rename_all = "camelCase")]
pub struct NumberDataPoint {
#[serde(deserialize_with = "deserialize_int_value", default)]
pub as_int: Option<String>,
pub as_double: Option<f64>,
pub attributes: Vec<KeyValue>,
#[serde(deserialize_with = "deserialize_int_value", default)]
pub time_unix_nano: Option<String>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(default, rename_all = "camelCase")]
pub struct ExportLogsRequest {
pub resource_logs: Vec<ResourceLog>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(default, rename_all = "camelCase")]
pub struct ResourceLog {
pub resource: Resource,
pub scope_logs: Vec<ScopeLog>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(default, rename_all = "camelCase")]
pub struct ScopeLog {
pub log_records: Vec<LogRecord>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(default, rename_all = "camelCase")]
pub struct LogRecord {
#[serde(deserialize_with = "deserialize_int_value", default)]
pub time_unix_nano: Option<String>,
pub body: Option<AnyValue>,
pub attributes: Vec<KeyValue>,
pub severity_text: Option<String>,
}