use std::collections::HashMap;
use desc::Desc;
use proto::{self, LabelPair};
use std::cmp::{Ord, Ordering, Eq, PartialOrd};
pub const SEPARATOR_BYTE: u8 = 0xFF;
pub trait Collector: Sync + Send {
fn desc(&self) -> &Desc;
fn collect(&self) -> proto::MetricFamily;
}
pub trait Metric: Sync + Send + Clone {
fn metric(&self) -> proto::Metric;
}
#[derive(Debug)]
pub struct Opts {
pub namespace: String,
pub subsystem: String,
pub name: String,
pub help: String,
pub const_labels: HashMap<String, String>,
}
impl Opts {
pub fn new<S: Into<String>>(name: S, help: S) -> Opts {
Opts {
namespace: "".to_owned(),
subsystem: "".to_owned(),
name: name.into(),
help: help.into(),
const_labels: HashMap::new(),
}
}
pub fn namespace<S: Into<String>>(mut self, namesapce: S) -> Self {
self.namespace = namesapce.into();
self
}
pub fn subsystem<S: Into<String>>(mut self, subsystem: S) -> Self {
self.subsystem = subsystem.into();
self
}
pub fn const_labels(mut self, labels: HashMap<String, String>) -> Self {
self.const_labels = labels;
self
}
pub fn const_label<S: Into<String>>(mut self, name: S, value: S) -> Self {
self.const_labels.insert(name.into(), value.into());
self
}
pub fn fq_name(&self) -> String {
build_fq_name(&self.namespace, &self.subsystem, &self.name)
}
}
impl Ord for LabelPair {
fn cmp(&self, other: &LabelPair) -> Ordering {
self.get_name().cmp(other.get_name())
}
}
impl Eq for LabelPair {}
impl PartialOrd for LabelPair {
fn partial_cmp(&self, other: &LabelPair) -> Option<Ordering> {
Some(self.cmp(other))
}
}
pub fn build_fq_name(namespace: &str, subsystem: &str, name: &str) -> String {
if name.is_empty() {
return "".to_owned();
}
if !namespace.is_empty() && !subsystem.is_empty() {
return format!("{}_{}_{}", namespace, subsystem, name);
} else if !namespace.is_empty() {
return format!("{}_{}", namespace, name);
} else if !subsystem.is_empty() {
return format!("{}_{}", subsystem, name);
}
name.to_owned()
}
#[cfg(test)]
mod tests {
use std::cmp::{Ord, Ordering};
use super::*;
use proto::LabelPair;
fn new_label_pair(name: &str, value: &str) -> LabelPair {
let mut l = LabelPair::new();
l.set_name(name.to_owned());
l.set_value(value.to_owned());
l
}
#[test]
fn test_label_cmp() {
let tbl = vec![
("k1", "k2", Ordering::Less),
("k1", "k1", Ordering::Equal),
("k1", "k0", Ordering::Greater),
];
for (l1, l2, order) in tbl {
let lhs = new_label_pair(l1, l1);
let rhs = new_label_pair(l2, l2);
assert_eq!(lhs.cmp(&rhs), order);
}
}
#[test]
fn test_build_fq_name() {
let tbl = vec![
("a", "b", "c", "a_b_c"),
("", "b", "c", "b_c"),
("a", "", "c", "a_c"),
("", "", "c", "c"),
("a", "b", "", ""),
("a", "", "", ""),
("", "b", "", ""),
(" ", "", "", ""),
];
for (namespace, subsystem, name, res) in tbl {
assert_eq!(&build_fq_name(namespace, subsystem, name), res);
}
}
}