diff --git a/src/counter.rs b/src/counter.rs index 239e2982..8f36f4f3 100644 --- a/src/counter.rs +++ b/src/counter.rs @@ -44,10 +44,10 @@ impl GenericCounter

{ /// Create a [`GenericCounter`] with the `opts` options. pub fn with_opts(opts: Opts) -> Result { - 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 { + fn with_opts_and_label_values>(opts: &Opts, label_values: &[L]) -> Result { let v = Value::new(opts, ValueType::Counter, P::T::from_i64(0), label_values)?; Ok(Self { v: Arc::new(v) }) } @@ -126,7 +126,7 @@ impl MetricVecBuilder for CounterVecBuilder

{ type M = GenericCounter

; type P = Opts; - fn build(&self, opts: &Opts, vals: &[&str]) -> Result { + fn build>(&self, opts: &Opts, vals: &[L]) -> Result { Self::M::with_opts_and_label_values(opts, vals) } } @@ -148,8 +148,11 @@ impl GenericCounterVec

{ /// Create a new [`GenericCounterVec`] based on the provided /// [`Opts`] and partitioned by the given label names. At least one label name must be /// provided. - pub fn new(opts: Opts, label_names: &[&str]) -> Result { - let variable_names = label_names.iter().map(|s| (*s).to_owned()).collect(); + pub fn new>(opts: Opts, label_names: &[L]) -> Result { + let variable_names = label_names + .iter() + .map(|s| (*s).as_ref().to_owned()) + .collect(); let opts = opts.variable_labels(variable_names); let metric_vec = MetricVec::create(proto::MetricType::COUNTER, CounterVecBuilder::new(), opts)?; @@ -283,7 +286,10 @@ impl GenericLocalCounterVec

{ /// Get a [`GenericLocalCounter`] by label values. /// See more [MetricVec::with_label_values]. - pub fn with_label_values<'a>(&'a mut self, vals: &[&str]) -> &'a mut GenericLocalCounter

{ + pub fn with_label_values<'a, L: AsRef>( + &'a mut self, + vals: &[L], + ) -> &'a mut GenericLocalCounter

{ let hash = self.vec.v.hash_label_values(vals).unwrap(); let vec = &self.vec; self.local @@ -293,7 +299,7 @@ impl GenericLocalCounterVec

{ /// Remove a [`GenericLocalCounter`] by label values. /// See more [MetricVec::remove_label_values]. - pub fn remove_label_values(&mut self, vals: &[&str]) -> Result<()> { + pub fn remove_label_values>(&mut self, vals: &[L]) -> Result<()> { let hash = self.vec.v.hash_label_values(vals)?; self.local.remove(&hash); self.vec.v.delete_label_values(vals) diff --git a/src/gauge.rs b/src/gauge.rs index 83eba2b1..d642b0ce 100644 --- a/src/gauge.rs +++ b/src/gauge.rs @@ -43,10 +43,10 @@ impl GenericGauge

{ /// Create a [`GenericGauge`] with the `opts` options. pub fn with_opts(opts: Opts) -> Result { - 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 { + fn with_opts_and_label_values>(opts: &Opts, label_values: &[L]) -> Result { let v = Value::new(opts, ValueType::Gauge, P::T::from_i64(0), label_values)?; Ok(Self { v: Arc::new(v) }) } @@ -129,7 +129,7 @@ impl MetricVecBuilder for GaugeVecBuilder

{ type M = GenericGauge

; type P = Opts; - fn build(&self, opts: &Opts, vals: &[&str]) -> Result { + fn build>(&self, opts: &Opts, vals: &[L]) -> Result { Self::M::with_opts_and_label_values(opts, vals) } } @@ -151,8 +151,11 @@ impl GenericGaugeVec

{ /// Create a new [`GenericGaugeVec`] based on the provided /// [`Opts`] and partitioned by the given label names. At least one label name must /// be provided. - pub fn new(opts: Opts, label_names: &[&str]) -> Result { - let variable_names = label_names.iter().map(|s| (*s).to_owned()).collect(); + pub fn new>(opts: Opts, label_names: &[L]) -> Result { + let variable_names = label_names + .iter() + .map(|s| (*s).as_ref().to_owned()) + .collect(); let opts = opts.variable_labels(variable_names); let metric_vec = MetricVec::create(proto::MetricType::GAUGE, GaugeVecBuilder::new(), opts)?; diff --git a/src/histogram.rs b/src/histogram.rs index 78480541..b9500eae 100644 --- a/src/histogram.rs +++ b/src/histogram.rs @@ -327,7 +327,7 @@ pub struct HistogramCore { } impl HistogramCore { - pub fn new(opts: &HistogramOpts, label_values: &[&str]) -> Result { + pub fn new>(opts: &HistogramOpts, label_values: &[L]) -> Result { let desc = opts.describe()?; for name in &desc.variable_labels { @@ -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::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>( opts: &HistogramOpts, - label_values: &[&str], + label_values: &[L], ) -> Result { let core = HistogramCore::new(opts, label_values)?; @@ -783,7 +783,7 @@ impl MetricVecBuilder for HistogramVecBuilder { type M = Histogram; type P = HistogramOpts; - fn build(&self, opts: &HistogramOpts, vals: &[&str]) -> Result { + fn build>(&self, opts: &HistogramOpts, vals: &[L]) -> Result { Histogram::with_opts_and_label_values(opts, vals) } } @@ -798,8 +798,11 @@ impl HistogramVec { /// Create a new [`HistogramVec`] based on the provided /// [`HistogramOpts`] and partitioned by the given label names. At least /// one label name must be provided. - pub fn new(opts: HistogramOpts, label_names: &[&str]) -> Result { - let variable_names = label_names.iter().map(|s| (*s).to_owned()).collect(); + pub fn new>(opts: HistogramOpts, label_names: &[L]) -> Result { + let variable_names = label_names + .iter() + .map(|s| (*s).as_ref().to_owned()) + .collect(); let opts = opts.variable_labels(variable_names); let metric_vec = MetricVec::create(proto::MetricType::HISTOGRAM, HistogramVecBuilder {}, opts)?; @@ -1168,7 +1171,7 @@ impl LocalHistogramVec { /// Get a [`LocalHistogram`] by label values. /// See more [`MetricVec::with_label_values`]. - pub fn with_label_values<'a>(&'a mut self, vals: &[&str]) -> &'a LocalHistogram { + pub fn with_label_values<'a, L: AsRef>(&'a mut self, vals: &[L]) -> &'a LocalHistogram { let hash = self.vec.v.hash_label_values(vals).unwrap(); let vec = &self.vec; self.local @@ -1178,7 +1181,7 @@ impl LocalHistogramVec { /// Remove a [`LocalHistogram`] by label values. /// See more [`MetricVec::remove_label_values`]. - pub fn remove_label_values(&mut self, vals: &[&str]) -> Result<()> { + pub fn remove_label_values>(&mut self, vals: &[L]) -> Result<()> { let hash = self.vec.v.hash_label_values(vals)?; self.local.remove(&hash); self.vec.v.delete_label_values(vals) diff --git a/src/value.rs b/src/value.rs index 87b2ede2..a14a1eb4 100644 --- a/src/value.rs +++ b/src/value.rs @@ -37,11 +37,11 @@ pub struct Value { } impl Value

{ - pub fn new( + pub fn new>( describer: &D, val_type: ValueType, val: P::T, - label_values: &[&str], + label_values: &[L], ) -> Result { let desc = describer.describe()?; let label_pairs = make_label_pairs(&desc, label_values)?; @@ -115,7 +115,7 @@ impl Value

{ } } -pub fn make_label_pairs(desc: &Desc, label_values: &[&str]) -> Result> { +pub fn make_label_pairs>(desc: &Desc, label_values: &[L]) -> Result> { if desc.variable_labels.len() != label_values.len() { return Err(Error::InconsistentCardinality { expect: desc.variable_labels.len(), @@ -136,7 +136,7 @@ pub fn make_label_pairs(desc: &Desc, label_values: &[&str]) -> Result Result; + fn build>(&self, _: &Self::P, _: &[L]) -> Result; } #[derive(Debug)] @@ -49,7 +49,7 @@ impl MetricVecCore { m } - pub fn get_metric_with_label_values(&self, vals: &[&str]) -> Result { + pub fn get_metric_with_label_values>(&self, vals: &[L]) -> Result { let h = self.hash_label_values(vals)?; if let Some(metric) = self.children.read().get(&h).cloned() { @@ -70,12 +70,20 @@ impl MetricVecCore { self.get_or_create_metric(h, &vals) } - pub fn delete_label_values(&self, vals: &[&str]) -> Result<()> { + pub fn delete_label_values>(&self, vals: &[L]) -> Result<()> { let h = self.hash_label_values(vals)?; let mut children = self.children.write(); if children.remove(&h).is_none() { - return Err(Error::Msg(format!("missing label values {:?}", vals))); + let format_labels = vals + .iter() + .map(|l| l.as_ref()) + .collect::>() + .join(", "); + return Err(Error::Msg(format!( + "missing label values [{}]", + format_labels + ))); } Ok(()) @@ -97,7 +105,7 @@ impl MetricVecCore { self.children.write().clear(); } - pub(crate) fn hash_label_values(&self, vals: &[&str]) -> Result { + pub(crate) fn hash_label_values>(&self, vals: &[L]) -> Result { if vals.len() != self.desc.variable_labels.len() { return Err(Error::InconsistentCardinality { expect: self.desc.variable_labels.len(), @@ -107,7 +115,7 @@ impl MetricVecCore { let mut h = FnvHasher::default(); for val in vals { - h.write(val.as_bytes()); + h.write(val.as_ref().as_bytes()); } Ok(h.finish()) @@ -153,7 +161,7 @@ impl MetricVecCore { Ok(values) } - fn get_or_create_metric(&self, hash: u64, label_values: &[&str]) -> Result { + fn get_or_create_metric>(&self, hash: u64, label_values: &[L]) -> Result { let mut children = self.children.write(); // Check exist first. if let Some(metric) = children.get(&hash).cloned() { @@ -221,7 +229,7 @@ impl MetricVec { /// an alternative to avoid that type of mistake. For higher label numbers, the /// latter has a much more readable (albeit more verbose) syntax, but it comes /// with a performance overhead (for creating and processing the Labels map). - pub fn get_metric_with_label_values(&self, vals: &[&str]) -> Result { + pub fn get_metric_with_label_values>(&self, vals: &[L]) -> Result { self.v.get_metric_with_label_values(vals) } @@ -254,7 +262,7 @@ impl MetricVec { /// ).unwrap(); /// vec.with_label_values(&["404", "POST"]).inc() /// ``` - pub fn with_label_values(&self, vals: &[&str]) -> T::M { + pub fn with_label_values>(&self, vals: &[L]) -> T::M { self.get_metric_with_label_values(vals).unwrap() } @@ -277,7 +285,7 @@ impl MetricVec { /// alternative to avoid that type of mistake. For higher label numbers, the /// latter has a much more readable (albeit more verbose) syntax, but it comes /// with a performance overhead (for creating and processing the Labels map). - pub fn remove_label_values(&self, vals: &[&str]) -> Result<()> { + pub fn remove_label_values>(&self, vals: &[L]) -> Result<()> { self.v.delete_label_values(vals) }