Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 58 additions & 3 deletions src/counter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ impl<P: Atomic> GenericCounter<P> {

/// Create a [`GenericCounter`] with the `opts` options.
pub fn with_opts(opts: Opts) -> Result<Self> {
Self::with_opts_and_label_values(&opts, &[])
Self::with_opts_and_label_values::<&str>(&opts, &[])
}

fn with_opts_and_label_values(opts: &Opts, label_values: &[&str]) -> Result<Self> {
fn with_opts_and_label_values<V: AsRef<str>>(opts: &Opts, label_values: &[V]) -> Result<Self> {
let v = Value::new(opts, ValueType::Counter, P::T::from_i64(0), label_values)?;
Ok(Self { v: Arc::new(v) })
}
Expand Down Expand Up @@ -126,7 +126,7 @@ impl<P: Atomic> MetricVecBuilder for CounterVecBuilder<P> {
type M = GenericCounter<P>;
type P = Opts;

fn build(&self, opts: &Opts, vals: &[&str]) -> Result<Self::M> {
fn build<V: AsRef<str>>(&self, opts: &Opts, vals: &[V]) -> Result<Self::M> {
Self::M::with_opts_and_label_values(opts, vals)
}
}
Expand Down Expand Up @@ -452,6 +452,40 @@ mod tests {
assert!(vec.remove(&labels3).is_err());
}

#[test]
fn test_counter_vec_with_owned_labels() {
let vec = CounterVec::new(
Opts::new("test_couter_vec", "test counter vec help"),
&["l1", "l2"],
)
.unwrap();

let v1 = "v1".to_string();
let v2 = "v2".to_string();

let mut labels = HashMap::new();
labels.insert("l1", v1.clone());
labels.insert("l2", v2.clone());
assert!(vec.remove(&labels).is_err());

vec.with(&labels).inc();
assert!(vec.remove(&labels).is_ok());
assert!(vec.remove(&labels).is_err());

let mut labels2 = HashMap::new();
labels2.insert("l1", v2.clone());
labels2.insert("l2", v1.clone());

vec.with(&labels).inc();
assert!(vec.remove(&labels2).is_err());

vec.with(&labels).inc();

let mut labels3 = HashMap::new();
labels3.insert("l1", v1.clone());
assert!(vec.remove(&labels3).is_err());
}

#[test]
fn test_int_counter_vec() {
let vec = IntCounterVec::new(Opts::new("foo", "bar"), &["l1", "l2"]).unwrap();
Expand Down Expand Up @@ -491,6 +525,27 @@ mod tests {
assert!(vec.remove_label_values(&["v1", "v3"]).is_err());
}

#[test]
fn test_counter_vec_with_owned_label_values() {
let vec = CounterVec::new(
Opts::new("test_vec", "test counter vec help"),
&["l1", "l2"],
)
.unwrap();

let v1 = "v1".to_string();
let v2 = "v2".to_string();
let v3 = "v3".to_string();

assert!(vec.remove_label_values(&[v1.clone(), v2.clone()]).is_err());
vec.with_label_values(&[v1.clone(), v2.clone()]).inc();
assert!(vec.remove_label_values(&[v1.clone(), v2.clone()]).is_ok());

vec.with_label_values(&[v1.clone(), v2.clone()]).inc();
assert!(vec.remove_label_values(&[v1.clone()]).is_err());
assert!(vec.remove_label_values(&[v1.clone(), v3.clone()]).is_err());
}

#[test]
fn test_counter_vec_local() {
let vec = CounterVec::new(
Expand Down
55 changes: 52 additions & 3 deletions src/gauge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ impl<P: Atomic> GenericGauge<P> {

/// Create a [`GenericGauge`] with the `opts` options.
pub fn with_opts(opts: Opts) -> Result<Self> {
Self::with_opts_and_label_values(&opts, &[])
Self::with_opts_and_label_values::<&str>(&opts, &[])
}

fn with_opts_and_label_values(opts: &Opts, label_values: &[&str]) -> Result<Self> {
fn with_opts_and_label_values<V: AsRef<str>>(opts: &Opts, label_values: &[V]) -> Result<Self> {
let v = Value::new(opts, ValueType::Gauge, P::T::from_i64(0), label_values)?;
Ok(Self { v: Arc::new(v) })
}
Expand Down Expand Up @@ -129,7 +129,7 @@ impl<P: Atomic> MetricVecBuilder for GaugeVecBuilder<P> {
type M = GenericGauge<P>;
type P = Opts;

fn build(&self, opts: &Opts, vals: &[&str]) -> Result<Self::M> {
fn build<V: AsRef<str>>(&self, opts: &Opts, vals: &[V]) -> Result<Self::M> {
Self::M::with_opts_and_label_values(opts, vals)
}
}
Expand Down Expand Up @@ -218,6 +218,29 @@ mod tests {
assert!(vec.remove(&labels).is_err());
}

#[test]
fn test_gauge_vec_with_owned_labels() {
let vec = GaugeVec::new(
Opts::new("test_gauge_vec", "test gauge vec help"),
&["l1", "l2"],
)
.unwrap();

let mut labels = HashMap::new();
labels.insert("l1", "v1");
labels.insert("l2", "v2");
assert!(vec.remove(&labels).is_err());

vec.with(&labels).inc();
vec.with(&labels).dec();
vec.with(&labels).add(42.0);
vec.with(&labels).sub(42.0);
vec.with(&labels).set(42.0);

assert!(vec.remove(&labels).is_ok());
assert!(vec.remove(&labels).is_err());
}

#[test]
fn test_gauge_vec_with_label_values() {
let vec = GaugeVec::new(
Expand All @@ -239,4 +262,30 @@ mod tests {
assert!(vec.remove_label_values(&["v1"]).is_err());
assert!(vec.remove_label_values(&["v1", "v3"]).is_err());
}

#[test]
fn test_gauge_vec_with_owned_label_values() {
let vec = GaugeVec::new(
Opts::new("test_gauge_vec", "test gauge vec help"),
&["l1", "l2"],
)
.unwrap();

let v1 = "v1".to_string();
let v2 = "v2".to_string();
let v3 = "v3".to_string();

assert!(vec.remove_label_values(&[v1.clone(), v2.clone()]).is_err());
vec.with_label_values(&[v1.clone(), v2.clone()]).inc();
assert!(vec.remove_label_values(&[v1.clone(), v2.clone()]).is_ok());

vec.with_label_values(&[v1.clone(), v2.clone()]).inc();
vec.with_label_values(&[v1.clone(), v2.clone()]).dec();
vec.with_label_values(&[v1.clone(), v2.clone()]).add(42.0);
vec.with_label_values(&[v1.clone(), v2.clone()]).sub(42.0);
vec.with_label_values(&[v1.clone(), v2.clone()]).set(42.0);

assert!(vec.remove_label_values(&[v1.clone()]).is_err());
assert!(vec.remove_label_values(&[v1.clone(), v3.clone()]).is_err());
}
}
31 changes: 26 additions & 5 deletions src/histogram.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ pub struct HistogramCore {
}

impl HistogramCore {
pub fn new(opts: &HistogramOpts, label_values: &[&str]) -> Result<HistogramCore> {
pub fn new<V: AsRef<str>>(opts: &HistogramOpts, label_values: &[V]) -> Result<HistogramCore> {
let desc = opts.describe()?;

for name in &desc.variable_labels {
Expand Down Expand Up @@ -674,12 +674,12 @@ pub struct Histogram {
impl Histogram {
/// `with_opts` creates a [`Histogram`] with the `opts` options.
pub fn with_opts(opts: HistogramOpts) -> Result<Histogram> {
Histogram::with_opts_and_label_values(&opts, &[])
Histogram::with_opts_and_label_values::<&str>(&opts, &[])
}

fn with_opts_and_label_values(
fn with_opts_and_label_values<V: AsRef<str>>(
opts: &HistogramOpts,
label_values: &[&str],
label_values: &[V],
) -> Result<Histogram> {
let core = HistogramCore::new(opts, label_values)?;

Expand Down Expand Up @@ -782,7 +782,7 @@ impl MetricVecBuilder for HistogramVecBuilder {
type M = Histogram;
type P = HistogramOpts;

fn build(&self, opts: &HistogramOpts, vals: &[&str]) -> Result<Histogram> {
fn build<V: AsRef<str>>(&self, opts: &HistogramOpts, vals: &[V]) -> Result<Histogram> {
Histogram::with_opts_and_label_values(opts, vals)
}
}
Expand Down Expand Up @@ -1389,6 +1389,27 @@ mod tests {
assert!(vec.remove_label_values(&["v1", "v3"]).is_err());
}

#[test]
fn test_histogram_vec_with_owned_label_values() {
let vec = HistogramVec::new(
HistogramOpts::new("test_histogram_vec", "test histogram vec help"),
&["l1", "l2"],
)
.unwrap();

let v1 = "v1".to_string();
let v2 = "v2".to_string();
let v3 = "v3".to_string();

assert!(vec.remove_label_values(&[v1.clone(), v2.clone()]).is_err());
vec.with_label_values(&[v1.clone(), v2.clone()])
.observe(1.0);
assert!(vec.remove_label_values(&[v1.clone(), v2.clone()]).is_ok());

assert!(vec.remove_label_values(&[v1.clone()]).is_err());
assert!(vec.remove_label_values(&[v1.clone(), v3.clone()]).is_err());
}

#[test]
fn test_histogram_vec_with_opts_buckets() {
let labels = ["l1", "l2"];
Expand Down
8 changes: 4 additions & 4 deletions src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ pub struct Value<P: Atomic> {
}

impl<P: Atomic> Value<P> {
pub fn new<D: Describer>(
pub fn new<D: Describer, V: AsRef<str>>(
describer: &D,
val_type: ValueType,
val: P::T,
label_values: &[&str],
label_values: &[V],
) -> Result<Self> {
let desc = describer.describe()?;
let label_pairs = make_label_pairs(&desc, label_values)?;
Expand Down Expand Up @@ -114,7 +114,7 @@ impl<P: Atomic> Value<P> {
}
}

pub fn make_label_pairs(desc: &Desc, label_values: &[&str]) -> Result<Vec<LabelPair>> {
pub fn make_label_pairs<V: AsRef<str>>(desc: &Desc, label_values: &[V]) -> Result<Vec<LabelPair>> {
if desc.variable_labels.len() != label_values.len() {
return Err(Error::InconsistentCardinality {
expect: desc.variable_labels.len(),
Expand All @@ -135,7 +135,7 @@ pub fn make_label_pairs(desc: &Desc, label_values: &[&str]) -> Result<Vec<LabelP
for (i, n) in desc.variable_labels.iter().enumerate() {
let mut label_pair = LabelPair::default();
label_pair.set_name(n.clone());
label_pair.set_value(label_values[i].to_owned());
label_pair.set_value(label_values[i].as_ref().to_owned());
label_pairs.push(label_pair);
}

Expand Down
Loading