use metric::{TagIter, TagMap};
use std::collections::HashSet;
use time;
#[derive(PartialEq, Debug, Serialize, Deserialize, Clone)]
pub struct LogLine {
pub time: i64,
pub path: String,
pub value: String,
pub fields: TagMap,
pub tags: Option<TagMap>,
}
impl LogLine {
pub fn new<S>(path: S, value: S) -> LogLine
where
S: Into<String>,
{
LogLine {
path: path.into(),
value: value.into(),
time: time::now(),
tags: Default::default(),
fields: Default::default(),
}
}
pub fn time(mut self, time: i64) -> LogLine {
self.time = time;
self
}
pub fn insert_field<S>(mut self, key: S, val: S) -> LogLine
where
S: Into<String>,
{
self.fields.insert(key.into(), val.into());
self
}
pub fn insert_tag<S>(&mut self, key: S, val: S) -> Option<String>
where
S: Into<String>,
{
if let Some(ref mut tags) = self.tags {
tags.insert(key.into(), val.into())
} else {
let mut tags = TagMap::default();
let res = tags.insert(key.into(), val.into());
self.tags = Some(tags);
res
}
}
pub fn remove_tag(&mut self, key: &str) -> Option<String> {
if let Some(ref mut tags) = self.tags {
tags.remove(key)
} else {
None
}
}
pub fn overlay_tag<S>(mut self, key: S, val: S) -> LogLine
where
S: Into<String>,
{
let _ = self.insert_tag(key, val);
self
}
pub fn overlay_tags_from_map(mut self, map: &TagMap) -> LogLine {
if let Some(ref mut tags) = self.tags {
for (k, v) in map.iter() {
tags.insert(k.clone(), v.clone());
}
} else if !map.is_empty() {
self.tags = Some(map.clone());
}
self
}
pub fn get_from_tags<'a>(
&'a mut self,
key: &'a str,
defaults: &'a TagMap,
) -> Option<&'a String> {
if let Some(ref mut tags) = self.tags {
match tags.get(key) {
Some(v) => Some(v),
None => defaults.get(key),
}
} else {
defaults.get(key)
}
}
pub fn tags<'a>(&'a self, defaults: &'a TagMap) -> TagIter<'a> {
if let Some(ref tags) = self.tags {
TagIter::Double {
iters_exhausted: false,
seen_keys: HashSet::new(),
defaults: defaults.iter(),
iters: tags.iter(),
}
} else {
TagIter::Single {
defaults: defaults.iter(),
}
}
}
}