use std::collections::BTreeMap;
use crate::wire::MetricType;
#[derive(Clone, Default, PartialEq, Eq)]
pub struct MetricOptions {
pub(crate) kind: Option<MetricType>,
pub(crate) labels: BTreeMap<String, String>,
pub(crate) help: Option<String>,
}
impl core::fmt::Debug for MetricOptions {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("MetricOptions")
.field("kind", &self.kind)
.field("labels", &self.labels.len())
.field("help", &self.help.is_some())
.finish()
}
}
impl MetricOptions {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn kind(mut self, kind: MetricType) -> Self {
self.kind = Some(kind);
self
}
#[must_use]
pub fn label(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.labels.insert(key.into(), value.into());
self
}
#[must_use]
pub fn help(mut self, text: impl Into<String>) -> Self {
self.help = Some(text.into());
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn metric_options_debug_hides_labels_and_help() {
let options = MetricOptions::new()
.kind(MetricType::Counter)
.label("model", "SECRET-LABEL-VALUE")
.help("SECRET HELP TEXT");
let rendered = format!("{options:?}");
assert_eq!(
rendered,
"MetricOptions { kind: Some(Counter), labels: 1, help: true }"
);
assert!(
!rendered.contains("SECRET-LABEL-VALUE") && !rendered.contains("SECRET HELP TEXT"),
"a label or help text reached the Debug output: {rendered}"
);
}
}