use std::sync::Arc;
use crate::value::FieldValue;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(into = "EntryRepr", from = "EntryRepr"))]
pub struct Entry {
pub name: String,
pub msg_type: u8,
pub timestamp_usec: Option<u64>,
pub(crate) labels: Arc<[String]>,
pub(crate) values: Vec<FieldValue>,
}
impl Entry {
pub fn get(&self, field: &str) -> Option<&FieldValue> {
let idx = self.labels.iter().position(|l| l == field)?;
self.values.get(idx)
}
pub fn get_f64(&self, field: &str) -> Option<f64> {
self.get(field).and_then(|v| v.as_f64())
}
pub fn get_i64(&self, field: &str) -> Option<i64> {
self.get(field).and_then(|v| v.as_i64())
}
pub fn get_u64(&self, field: &str) -> Option<u64> {
self.get(field).and_then(|v| v.as_u64())
}
pub fn get_str(&self, field: &str) -> Option<&str> {
self.get(field).and_then(|v| v.as_str())
}
pub fn fields(&self) -> impl Iterator<Item = (&str, &FieldValue)> {
self.labels
.iter()
.map(|l| l.as_str())
.zip(self.values.iter())
}
#[must_use]
pub fn labels(&self) -> &[String] {
&self.labels
}
#[must_use]
pub fn values(&self) -> &[FieldValue] {
&self.values
}
#[must_use]
pub fn len(&self) -> usize {
self.values.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.values.is_empty()
}
}
#[cfg(feature = "serde")]
#[derive(serde::Serialize, serde::Deserialize)]
struct EntryRepr {
name: String,
msg_type: u8,
timestamp_usec: Option<u64>,
fields: Vec<(String, FieldValue)>,
}
#[cfg(feature = "serde")]
impl From<Entry> for EntryRepr {
fn from(e: Entry) -> Self {
let fields = e.labels.iter().cloned().zip(e.values).collect();
EntryRepr {
name: e.name,
msg_type: e.msg_type,
timestamp_usec: e.timestamp_usec,
fields,
}
}
}
#[cfg(feature = "serde")]
impl From<EntryRepr> for Entry {
fn from(r: EntryRepr) -> Self {
let (labels, values): (Vec<String>, Vec<FieldValue>) = r.fields.into_iter().unzip();
Entry {
name: r.name,
msg_type: r.msg_type,
timestamp_usec: r.timestamp_usec,
labels: labels.into(),
values,
}
}
}