use std::sync::Arc;
use proto;
use desc::Desc;
use errors::Result;
use value::{Value, ValueType};
use metrics::{Opts, Collector, Metric};
use vec::{MetricVec, MetricVecBuilder};
#[derive(Clone)]
pub struct Untyped {
v: Arc<Value>,
}
impl Untyped {
pub fn new<S: Into<String>>(name: S, help: S) -> Result<Untyped> {
let opts = Opts::new(name, help);
Untyped::with_opts(opts)
}
pub fn with_opts(opts: Opts) -> Result<Untyped> {
let desc = try!(Desc::new(opts.fq_name(), opts.help, vec![], opts.const_labels));
Untyped::with_desc(desc, &[])
}
fn with_desc(desc: Desc, label_values: &[&str]) -> Result<Untyped> {
let v = try!(Value::new(desc, ValueType::Untyped, 0.0, label_values));
Ok(Untyped { v: Arc::new(v) })
}
}
impl Untyped {
#[inline]
pub fn set(&self, v: f64) {
self.v.set(v);
}
#[inline]
pub fn inc(&self) {
self.add(1.0);
}
#[inline]
pub fn dec(&self) {
self.sub(1.0);
}
#[inline]
pub fn add(&self, v: f64) {
self.v.inc_by(v);
}
#[inline]
pub fn sub(&self, v: f64) {
self.v.dec_by(v);
}
#[inline]
pub fn get(&self) -> f64 {
self.v.get()
}
}
impl Collector for Untyped {
fn desc(&self) -> &Desc {
&self.v.desc
}
fn collect(&self) -> proto::MetricFamily {
self.v.collect()
}
}
impl Metric for Untyped {
fn metric(&self) -> proto::Metric {
self.v.metric()
}
}
#[derive(Clone)]
pub struct UntypedVecBuilder {}
impl MetricVecBuilder for UntypedVecBuilder {
type Output = Untyped;
fn build(&self, desc: &Desc, vals: &[&str]) -> Result<Untyped> {
Untyped::with_desc(desc.clone(), vals)
}
}
pub type UntypedVec = MetricVec<UntypedVecBuilder>;
impl UntypedVec {
pub fn new(opts: Opts, label_names: &[&str]) -> Result<UntypedVec> {
let variable_names = label_names.iter().map(|s| (*s).to_owned()).collect();
let desc = try!(Desc::new(opts.fq_name(), opts.help, variable_names, opts.const_labels));
let metric_vec = MetricVec::create(desc, proto::MetricType::UNTYPED, UntypedVecBuilder {});
Ok(metric_vec as UntypedVec)
}
}
#[cfg(test)]
mod tests {
use metrics::{Opts, Collector};
use super::*;
#[test]
fn test_untyped() {
let opts = Opts::new("test", "test help").const_label("a", "1").const_label("b", "2");
let untyped = Untyped::with_opts(opts).unwrap();
untyped.inc();
assert_eq!(untyped.get() as u64, 1);
untyped.add(42.0);
assert_eq!(untyped.get() as u64, 43);
untyped.sub(42.0);
assert_eq!(untyped.get() as u64, 1);
untyped.dec();
assert_eq!(untyped.get() as u64, 0);
untyped.set(42.0);
assert_eq!(untyped.get() as u64, 42);
let mf = untyped.collect();
let m = mf.get_metric().as_ref().get(0).unwrap();
assert_eq!(m.get_label().len(), 2);
assert_eq!(m.get_untyped().get_value() as u64, 42);
}
}