Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(encoding): impl EncodeLabelValue for bool #237

Merged
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
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Implement `Atomic<u64>` for `AtomicU64` for gauges.
See [PR 226].

[PR 226]: https://github.com/prometheus/client_rust/pull/198
- Implement `EnableLabelValue` for `bool`.
See [PR 237]

[PR 173]: https://github.com/prometheus/client_rust/pull/173
[PR 198]: https://github.com/prometheus/client_rust/pull/198
[PR 226]: https://github.com/prometheus/client_rust/pull/226
[PR 237]: https://github.com/prometheus/client_rust/pull/237

### Added

Expand Down
179 changes: 93 additions & 86 deletions src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,6 @@ pub trait EncodeLabelSet {
fn encode(&self, encoder: LabelSetEncoder) -> Result<(), std::fmt::Error>;
}

impl<'a> From<text::LabelSetEncoder<'a>> for LabelSetEncoder<'a> {
fn from(e: text::LabelSetEncoder<'a>) -> Self {
Self(LabelSetEncoderInner::Text(e))
}
}

/// Encoder for a label set.
#[derive(Debug)]
pub struct LabelSetEncoder<'a>(LabelSetEncoderInner<'a>);
Expand All @@ -223,6 +217,12 @@ enum LabelSetEncoderInner<'a> {
Protobuf(protobuf::LabelSetEncoder<'a>),
}

impl<'a> From<text::LabelSetEncoder<'a>> for LabelSetEncoder<'a> {
fn from(e: text::LabelSetEncoder<'a>) -> Self {
Self(LabelSetEncoderInner::Text(e))
}
}

#[cfg(feature = "protobuf")]
impl<'a> From<protobuf::LabelSetEncoder<'a>> for LabelSetEncoder<'a> {
fn from(e: protobuf::LabelSetEncoder<'a>) -> Self {
Expand All @@ -237,6 +237,42 @@ impl LabelSetEncoder<'_> {
}
}

impl<T: EncodeLabel, const N: usize> EncodeLabelSet for [T; N] {
fn encode(&self, encoder: LabelSetEncoder) -> Result<(), std::fmt::Error> {
self.as_ref().encode(encoder)
}
}

impl<T: EncodeLabel> EncodeLabelSet for &[T] {
fn encode(&self, mut encoder: LabelSetEncoder) -> Result<(), std::fmt::Error> {
if self.is_empty() {
return Ok(());
}

for label in self.iter() {
label.encode(encoder.encode_label())?
}

Ok(())
}
}

impl<T: EncodeLabel> EncodeLabelSet for Vec<T> {
fn encode(&self, encoder: LabelSetEncoder) -> Result<(), std::fmt::Error> {
self.as_slice().encode(encoder)
}
}

/// Uninhabited type to represent the lack of a label set for a metric
#[derive(Debug)]
pub enum NoLabelSet {}

impl EncodeLabelSet for NoLabelSet {
fn encode(&self, _encoder: LabelSetEncoder) -> Result<(), std::fmt::Error> {
Ok(())
}
}

/// An encodable label.
pub trait EncodeLabel {
/// Encode oneself into the given encoder.
Expand All @@ -247,10 +283,6 @@ pub trait EncodeLabel {
#[derive(Debug)]
pub struct LabelEncoder<'a>(LabelEncoderInner<'a>);

/// Uninhabited type to represent the lack of a label set for a metric
#[derive(Debug)]
pub enum NoLabelSet {}

#[derive(Debug)]
enum LabelEncoderInner<'a> {
Text(text::LabelEncoder<'a>),
Expand Down Expand Up @@ -283,6 +315,21 @@ impl LabelEncoder<'_> {
}
}

impl<K: EncodeLabelKey, V: EncodeLabelValue> EncodeLabel for (K, V) {
fn encode(&self, mut encoder: LabelEncoder) -> Result<(), std::fmt::Error> {
let (key, value) = self;

let mut label_key_encoder = encoder.encode_label_key()?;
key.encode(&mut label_key_encoder)?;

let mut label_value_encoder = label_key_encoder.encode_label_value()?;
value.encode(&mut label_value_encoder)?;
label_value_encoder.finish()?;

Ok(())
}
}

/// An encodable label key.
pub trait EncodeLabelKey {
/// Encode oneself into the given encoder.
Expand Down Expand Up @@ -330,52 +377,6 @@ impl<'a> LabelKeyEncoder<'a> {
)
}
}
impl<T: EncodeLabel, const N: usize> EncodeLabelSet for [T; N] {
fn encode(&self, encoder: LabelSetEncoder) -> Result<(), std::fmt::Error> {
self.as_ref().encode(encoder)
}
}

impl<T: EncodeLabel> EncodeLabelSet for &[T] {
fn encode(&self, mut encoder: LabelSetEncoder) -> Result<(), std::fmt::Error> {
if self.is_empty() {
return Ok(());
}

for label in self.iter() {
label.encode(encoder.encode_label())?
}

Ok(())
}
}

impl<T: EncodeLabel> EncodeLabelSet for Vec<T> {
fn encode(&self, encoder: LabelSetEncoder) -> Result<(), std::fmt::Error> {
self.as_slice().encode(encoder)
}
}

impl EncodeLabelSet for NoLabelSet {
fn encode(&self, _encoder: LabelSetEncoder) -> Result<(), std::fmt::Error> {
Ok(())
}
}

impl<K: EncodeLabelKey, V: EncodeLabelValue> EncodeLabel for (K, V) {
fn encode(&self, mut encoder: LabelEncoder) -> Result<(), std::fmt::Error> {
let (key, value) = self;

let mut label_key_encoder = encoder.encode_label_key()?;
key.encode(&mut label_key_encoder)?;

let mut label_value_encoder = label_key_encoder.encode_label_value()?;
value.encode(&mut label_value_encoder)?;
label_value_encoder.finish()?;

Ok(())
}
}

impl EncodeLabelKey for &str {
fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error> {
Expand Down Expand Up @@ -433,6 +434,13 @@ pub trait EncodeLabelValue {
#[derive(Debug)]
pub struct LabelValueEncoder<'a>(LabelValueEncoderInner<'a>);

#[derive(Debug)]
enum LabelValueEncoderInner<'a> {
Text(text::LabelValueEncoder<'a>),
#[cfg(feature = "protobuf")]
Protobuf(protobuf::LabelValueEncoder<'a>),
}

impl<'a> From<text::LabelValueEncoder<'a>> for LabelValueEncoder<'a> {
fn from(e: text::LabelValueEncoder<'a>) -> Self {
LabelValueEncoder(LabelValueEncoderInner::Text(e))
Expand All @@ -446,11 +454,10 @@ impl<'a> From<protobuf::LabelValueEncoder<'a>> for LabelValueEncoder<'a> {
}
}

#[derive(Debug)]
enum LabelValueEncoderInner<'a> {
Text(text::LabelValueEncoder<'a>),
#[cfg(feature = "protobuf")]
Protobuf(protobuf::LabelValueEncoder<'a>),
impl std::fmt::Write for LabelValueEncoder<'_> {
fn write_str(&mut self, s: &str) -> std::fmt::Result {
for_both_mut!(self, LabelValueEncoderInner, e, e.write_str(s))
}
}

impl LabelValueEncoder<'_> {
Expand All @@ -460,12 +467,6 @@ impl LabelValueEncoder<'_> {
}
}

impl std::fmt::Write for LabelValueEncoder<'_> {
fn write_str(&mut self, s: &str) -> std::fmt::Result {
for_both_mut!(self, LabelValueEncoderInner, e, e.write_str(s))
}
}

impl EncodeLabelValue for &str {
fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
encoder.write_str(self)?;
Expand Down Expand Up @@ -536,6 +537,12 @@ where
}
}

impl EncodeLabelValue for bool {
fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
encoder.write_str(if *self { "true" } else { "false" })
}
}
Comment on lines +540 to +544
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the record, i would support this addition, i think it's a pleasant and natural addition to the library.

that said, the reordering of impl blocks here is probably best left for a distinct pull request, as it introduces a lot of undue noise for reviewers to inspect.


macro_rules! impl_encode_label_value_for_integer {
($($t:ident),*) => {$(
impl EncodeLabelValue for $t {
Expand Down Expand Up @@ -678,6 +685,19 @@ enum CounterValueEncoderInner<'a> {
Protobuf(protobuf::CounterValueEncoder<'a>),
}

impl<'a> From<text::CounterValueEncoder<'a>> for CounterValueEncoder<'a> {
fn from(e: text::CounterValueEncoder<'a>) -> Self {
CounterValueEncoder(CounterValueEncoderInner::Text(e))
}
}

#[cfg(feature = "protobuf")]
impl<'a> From<protobuf::CounterValueEncoder<'a>> for CounterValueEncoder<'a> {
fn from(e: protobuf::CounterValueEncoder<'a>) -> Self {
CounterValueEncoder(CounterValueEncoderInner::Protobuf(e))
}
}

impl CounterValueEncoder<'_> {
fn encode_f64(&mut self, v: f64) -> Result<(), std::fmt::Error> {
for_both_mut!(self, CounterValueEncoderInner, e, e.encode_f64(v))
Expand Down Expand Up @@ -718,19 +738,6 @@ impl EncodeExemplarValue for u32 {
}
}

impl<'a> From<text::CounterValueEncoder<'a>> for CounterValueEncoder<'a> {
fn from(e: text::CounterValueEncoder<'a>) -> Self {
CounterValueEncoder(CounterValueEncoderInner::Text(e))
}
}

#[cfg(feature = "protobuf")]
impl<'a> From<protobuf::CounterValueEncoder<'a>> for CounterValueEncoder<'a> {
fn from(e: protobuf::CounterValueEncoder<'a>) -> Self {
CounterValueEncoder(CounterValueEncoderInner::Protobuf(e))
}
}

/// Encoder for an exemplar value.
#[derive(Debug)]
pub struct ExemplarValueEncoder<'a>(ExemplarValueEncoderInner<'a>);
Expand All @@ -742,12 +749,6 @@ enum ExemplarValueEncoderInner<'a> {
Protobuf(protobuf::ExemplarValueEncoder<'a>),
}

impl ExemplarValueEncoder<'_> {
fn encode(&mut self, v: f64) -> Result<(), std::fmt::Error> {
for_both_mut!(self, ExemplarValueEncoderInner, e, e.encode(v))
}
}

impl<'a> From<text::ExemplarValueEncoder<'a>> for ExemplarValueEncoder<'a> {
fn from(e: text::ExemplarValueEncoder<'a>) -> Self {
ExemplarValueEncoder(ExemplarValueEncoderInner::Text(e))
Expand All @@ -760,3 +761,9 @@ impl<'a> From<protobuf::ExemplarValueEncoder<'a>> for ExemplarValueEncoder<'a> {
ExemplarValueEncoder(ExemplarValueEncoderInner::Protobuf(e))
}
}

impl ExemplarValueEncoder<'_> {
fn encode(&mut self, v: f64) -> Result<(), std::fmt::Error> {
for_both_mut!(self, ExemplarValueEncoderInner, e, e.encode(v))
}
}
Loading