1#![allow(deprecated)]
4
5pub use prometheus_client_derive_encode::*;
6
7use crate::metrics::exemplar::Exemplar;
8use crate::metrics::MetricType;
9use crate::registry::{Prefix, Unit};
10use std::borrow::Cow;
11use std::collections::HashMap;
12use std::fmt::Write;
13use std::ops::Deref;
14use std::rc::Rc;
15use std::sync::Arc;
16use std::time::{SystemTime, UNIX_EPOCH};
17
18#[cfg(feature = "openmetrics_protobuf")]
19#[cfg_attr(docsrs, doc(cfg(feature = "openmetrics_protobuf")))]
20#[cfg_attr(
21 not(test),
22 deprecated(
23 note = "OpenMetrics protobuf support is deprecated. Use prometheus_protobuf instead."
24 )
25)]
26pub mod openmetrics_protobuf;
27#[cfg(feature = "prometheus_protobuf")]
28#[cfg_attr(docsrs, doc(cfg(feature = "prometheus_protobuf")))]
29pub mod prometheus_protobuf;
30pub mod text;
31
32#[cfg(feature = "openmetrics_protobuf")]
33#[deprecated(note = "Use openmetrics_protobuf instead.")]
34pub use openmetrics_protobuf as protobuf;
35
36#[derive(Clone, Copy, Debug)]
38pub struct NativeHistogram<'a> {
39 pub schema: i32,
41 pub zero_threshold: f64,
43 pub zero_count: u64,
45 pub negative: NativeHistogramBuckets<'a>,
47 pub positive: NativeHistogramBuckets<'a>,
49 pub created: Option<SystemTime>,
51}
52
53#[derive(Clone, Copy, Debug)]
55pub struct NativeHistogramBuckets<'a> {
56 pub spans: &'a [(i32, u32)],
58 pub deltas: &'a [i64],
60}
61
62macro_rules! for_both_mut {
63 ($self:expr, $inner:ident, $pattern:pat, $fn:expr) => {
64 match &mut $self.0 {
65 $inner::Text($pattern) => $fn,
66 #[cfg(feature = "openmetrics_protobuf")]
67 $inner::Protobuf($pattern) => $fn,
68 #[cfg(feature = "prometheus_protobuf")]
69 $inner::PrometheusProtobuf($pattern) => $fn,
70 }
71 };
72}
73
74macro_rules! for_both {
75 ($self:expr, $inner:ident, $pattern:pat, $fn:expr) => {
76 match $self.0 {
77 $inner::Text($pattern) => $fn,
78 #[cfg(feature = "openmetrics_protobuf")]
79 $inner::Protobuf($pattern) => $fn,
80 #[cfg(feature = "prometheus_protobuf")]
81 $inner::PrometheusProtobuf($pattern) => $fn,
82 }
83 };
84}
85
86pub trait EncodeMetric {
90 fn encode(&self, encoder: MetricEncoder) -> Result<(), std::fmt::Error>;
93
94 fn metric_type(&self) -> MetricType;
98
99 fn is_empty(&self) -> bool {
107 false
108 }
109}
110
111impl EncodeMetric for Box<dyn EncodeMetric> {
112 fn encode(&self, encoder: MetricEncoder) -> Result<(), std::fmt::Error> {
113 self.deref().encode(encoder)
114 }
115
116 fn metric_type(&self) -> MetricType {
117 self.deref().metric_type()
118 }
119}
120
121#[derive(Debug)]
123pub struct DescriptorEncoder<'a>(DescriptorEncoderInner<'a>);
124
125#[derive(Debug)]
126enum DescriptorEncoderInner<'a> {
127 Text(text::DescriptorEncoder<'a>),
128
129 #[cfg(feature = "openmetrics_protobuf")]
130 Protobuf(openmetrics_protobuf::DescriptorEncoder<'a>),
131
132 #[cfg(feature = "prometheus_protobuf")]
133 PrometheusProtobuf(prometheus_protobuf::DescriptorEncoder<'a>),
134}
135
136impl<'a> From<text::DescriptorEncoder<'a>> for DescriptorEncoder<'a> {
137 fn from(e: text::DescriptorEncoder<'a>) -> Self {
138 Self(DescriptorEncoderInner::Text(e))
139 }
140}
141
142#[cfg(feature = "openmetrics_protobuf")]
143impl<'a> From<openmetrics_protobuf::DescriptorEncoder<'a>> for DescriptorEncoder<'a> {
144 fn from(e: openmetrics_protobuf::DescriptorEncoder<'a>) -> Self {
145 Self(DescriptorEncoderInner::Protobuf(e))
146 }
147}
148
149#[cfg(feature = "prometheus_protobuf")]
150impl<'a> From<prometheus_protobuf::DescriptorEncoder<'a>> for DescriptorEncoder<'a> {
151 fn from(e: prometheus_protobuf::DescriptorEncoder<'a>) -> Self {
152 Self(DescriptorEncoderInner::PrometheusProtobuf(e))
153 }
154}
155
156impl DescriptorEncoder<'_> {
157 pub(crate) fn with_prefix_and_labels<'s>(
158 &'s mut self,
159 prefix: Option<&'s Prefix>,
160 labels: &'s [(Cow<'static, str>, Cow<'static, str>)],
161 ) -> DescriptorEncoder<'s> {
163 for_both_mut!(
164 self,
165 DescriptorEncoderInner,
166 e,
167 e.with_prefix_and_labels(prefix, labels).into()
168 )
169 }
170
171 pub fn encode_descriptor<'s>(
173 &'s mut self,
174 name: &'s str,
175 help: &str,
176 unit: Option<&'s Unit>,
177 metric_type: MetricType,
178 ) -> Result<MetricEncoder<'s>, std::fmt::Error> {
179 for_both_mut!(
180 self,
181 DescriptorEncoderInner,
182 e,
183 Ok(e.encode_descriptor(name, help, unit, metric_type)?.into())
184 )
185 }
186}
187
188#[derive(Debug)]
190pub struct MetricEncoder<'a>(MetricEncoderInner<'a>);
191
192#[derive(Debug)]
193enum MetricEncoderInner<'a> {
194 Text(text::MetricEncoder<'a>),
195
196 #[cfg(feature = "openmetrics_protobuf")]
197 Protobuf(openmetrics_protobuf::MetricEncoder<'a>),
198
199 #[cfg(feature = "prometheus_protobuf")]
200 PrometheusProtobuf(prometheus_protobuf::MetricEncoder<'a>),
201}
202
203impl<'a> From<text::MetricEncoder<'a>> for MetricEncoder<'a> {
204 fn from(e: text::MetricEncoder<'a>) -> Self {
205 Self(MetricEncoderInner::Text(e))
206 }
207}
208
209#[cfg(feature = "openmetrics_protobuf")]
210impl<'a> From<openmetrics_protobuf::MetricEncoder<'a>> for MetricEncoder<'a> {
211 fn from(e: openmetrics_protobuf::MetricEncoder<'a>) -> Self {
212 Self(MetricEncoderInner::Protobuf(e))
213 }
214}
215
216#[cfg(feature = "prometheus_protobuf")]
217impl<'a> From<prometheus_protobuf::MetricEncoder<'a>> for MetricEncoder<'a> {
218 fn from(e: prometheus_protobuf::MetricEncoder<'a>) -> Self {
219 Self(MetricEncoderInner::PrometheusProtobuf(e))
220 }
221}
222
223impl MetricEncoder<'_> {
224 pub fn encode_counter<
226 S: EncodeLabelSet,
227 CounterValue: EncodeCounterValue,
228 ExemplarValue: EncodeExemplarValue,
229 >(
230 &mut self,
231 v: &CounterValue,
232 exemplar: Option<&Exemplar<S, ExemplarValue>>,
233 ) -> Result<(), std::fmt::Error> {
234 for_both_mut!(self, MetricEncoderInner, e, e.encode_counter(v, exemplar))
235 }
236
237 pub fn encode_gauge<GaugeValue: EncodeGaugeValue>(
239 &mut self,
240 v: &GaugeValue,
241 ) -> Result<(), std::fmt::Error> {
242 for_both_mut!(self, MetricEncoderInner, e, e.encode_gauge(v))
243 }
244
245 pub fn encode_info(&mut self, label_set: &impl EncodeLabelSet) -> Result<(), std::fmt::Error> {
247 for_both_mut!(self, MetricEncoderInner, e, e.encode_info(label_set))
248 }
249
250 pub fn encode_histogram<S: EncodeLabelSet>(
252 &mut self,
253 sum: f64,
254 count: u64,
255 buckets: &[(f64, u64)],
256 exemplars: Option<&HashMap<usize, Exemplar<S, f64>>>,
257 ) -> Result<(), std::fmt::Error> {
258 for_both_mut!(
259 self,
260 MetricEncoderInner,
261 e,
262 e.encode_histogram(sum, count, buckets, exemplars)
263 )
264 }
265
266 pub fn encode_histogram_with_native<S: EncodeLabelSet>(
271 &mut self,
272 sum: f64,
273 count: u64,
274 buckets: &[(f64, u64)],
275 exemplars: Option<&HashMap<usize, Exemplar<S, f64>>>,
276 native: NativeHistogram<'_>,
277 ) -> Result<(), std::fmt::Error> {
278 for_both_mut!(
279 self,
280 MetricEncoderInner,
281 e,
282 e.encode_histogram_with_native(sum, count, buckets, exemplars, native)
283 )
284 }
285
286 pub fn encode_family<'s, S: EncodeLabelSet>(
288 &'s mut self,
289 label_set: &'s S,
290 ) -> Result<MetricEncoder<'s>, std::fmt::Error> {
291 for_both_mut!(
292 self,
293 MetricEncoderInner,
294 e,
295 e.encode_family(label_set).map(Into::into)
296 )
297 }
298}
299
300pub trait EncodeLabelSet {
302 fn encode(&self, encoder: &mut LabelSetEncoder) -> Result<(), std::fmt::Error>;
304}
305
306#[derive(Debug)]
308pub struct LabelSetEncoder<'a>(LabelSetEncoderInner<'a>);
309
310#[derive(Debug)]
311enum LabelSetEncoderInner<'a> {
312 Text(text::LabelSetEncoder<'a>),
313 #[cfg(feature = "openmetrics_protobuf")]
314 Protobuf(openmetrics_protobuf::LabelSetEncoder<'a>),
315 #[cfg(feature = "prometheus_protobuf")]
316 PrometheusProtobuf(prometheus_protobuf::LabelSetEncoder<'a>),
317}
318
319impl<'a> From<text::LabelSetEncoder<'a>> for LabelSetEncoder<'a> {
320 fn from(e: text::LabelSetEncoder<'a>) -> Self {
321 Self(LabelSetEncoderInner::Text(e))
322 }
323}
324
325#[cfg(feature = "openmetrics_protobuf")]
326impl<'a> From<openmetrics_protobuf::LabelSetEncoder<'a>> for LabelSetEncoder<'a> {
327 fn from(e: openmetrics_protobuf::LabelSetEncoder<'a>) -> Self {
328 Self(LabelSetEncoderInner::Protobuf(e))
329 }
330}
331
332#[cfg(feature = "prometheus_protobuf")]
333impl<'a> From<prometheus_protobuf::LabelSetEncoder<'a>> for LabelSetEncoder<'a> {
334 fn from(e: prometheus_protobuf::LabelSetEncoder<'a>) -> Self {
335 Self(LabelSetEncoderInner::PrometheusProtobuf(e))
336 }
337}
338
339impl LabelSetEncoder<'_> {
340 pub fn encode_label(&mut self) -> LabelEncoder<'_> {
342 for_both_mut!(self, LabelSetEncoderInner, e, e.encode_label().into())
343 }
344}
345
346impl<T: EncodeLabel, const N: usize> EncodeLabelSet for [T; N] {
347 fn encode(&self, encoder: &mut LabelSetEncoder) -> Result<(), std::fmt::Error> {
348 self.as_ref().encode(encoder)
349 }
350}
351
352impl<T: EncodeLabel> EncodeLabelSet for &[T] {
353 fn encode(&self, encoder: &mut LabelSetEncoder) -> Result<(), std::fmt::Error> {
354 if self.is_empty() {
355 return Ok(());
356 }
357
358 for label in self.iter() {
359 let encoder = encoder.encode_label();
360 label.encode(encoder)?
361 }
362
363 Ok(())
364 }
365}
366
367impl<T: EncodeLabel> EncodeLabelSet for Vec<T> {
368 fn encode(&self, encoder: &mut LabelSetEncoder) -> Result<(), std::fmt::Error> {
369 self.as_slice().encode(encoder)
370 }
371}
372
373impl<A, B> EncodeLabelSet for (A, B)
374where
375 A: EncodeLabelSet,
376 B: EncodeLabelSet,
377{
378 fn encode(&self, encoder: &mut LabelSetEncoder) -> Result<(), std::fmt::Error> {
379 let (a, b) = self;
380
381 a.encode(encoder)?;
382 b.encode(encoder)?;
383
384 Ok(())
385 }
386}
387
388#[derive(Debug)]
390pub enum NoLabelSet {}
391
392impl EncodeLabelSet for NoLabelSet {
393 fn encode(&self, _encoder: &mut LabelSetEncoder) -> Result<(), std::fmt::Error> {
394 Ok(())
395 }
396}
397
398pub trait EncodeLabel {
400 fn encode(&self, encoder: LabelEncoder) -> Result<(), std::fmt::Error>;
402}
403
404#[derive(Debug)]
406pub struct LabelEncoder<'a>(LabelEncoderInner<'a>);
407
408#[derive(Debug)]
409enum LabelEncoderInner<'a> {
410 Text(text::LabelEncoder<'a>),
411 #[cfg(feature = "openmetrics_protobuf")]
412 Protobuf(openmetrics_protobuf::LabelEncoder<'a>),
413 #[cfg(feature = "prometheus_protobuf")]
414 PrometheusProtobuf(prometheus_protobuf::LabelEncoder<'a>),
415}
416
417impl<'a> From<text::LabelEncoder<'a>> for LabelEncoder<'a> {
418 fn from(e: text::LabelEncoder<'a>) -> Self {
419 Self(LabelEncoderInner::Text(e))
420 }
421}
422
423#[cfg(feature = "openmetrics_protobuf")]
424impl<'a> From<openmetrics_protobuf::LabelEncoder<'a>> for LabelEncoder<'a> {
425 fn from(e: openmetrics_protobuf::LabelEncoder<'a>) -> Self {
426 Self(LabelEncoderInner::Protobuf(e))
427 }
428}
429
430#[cfg(feature = "prometheus_protobuf")]
431impl<'a> From<prometheus_protobuf::LabelEncoder<'a>> for LabelEncoder<'a> {
432 fn from(e: prometheus_protobuf::LabelEncoder<'a>) -> Self {
433 Self(LabelEncoderInner::PrometheusProtobuf(e))
434 }
435}
436
437impl LabelEncoder<'_> {
438 pub fn encode_label_key(&mut self) -> Result<LabelKeyEncoder<'_>, std::fmt::Error> {
440 for_both_mut!(
441 self,
442 LabelEncoderInner,
443 e,
444 e.encode_label_key().map(Into::into)
445 )
446 }
447}
448
449impl<K: EncodeLabelKey, V: EncodeLabelValue> EncodeLabel for (K, V) {
450 fn encode(&self, mut encoder: LabelEncoder) -> Result<(), std::fmt::Error> {
451 let (key, value) = self;
452
453 let mut label_key_encoder = encoder.encode_label_key()?;
454 key.encode(&mut label_key_encoder)?;
455
456 let mut label_value_encoder = label_key_encoder.encode_label_value()?;
457 value.encode(&mut label_value_encoder)?;
458 label_value_encoder.finish()?;
459
460 Ok(())
461 }
462}
463
464pub trait EncodeLabelKey {
466 fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error>;
468}
469
470#[derive(Debug)]
472pub struct LabelKeyEncoder<'a>(LabelKeyEncoderInner<'a>);
473
474#[derive(Debug)]
475enum LabelKeyEncoderInner<'a> {
476 Text(text::LabelKeyEncoder<'a>),
477 #[cfg(feature = "openmetrics_protobuf")]
478 Protobuf(openmetrics_protobuf::LabelKeyEncoder<'a>),
479 #[cfg(feature = "prometheus_protobuf")]
480 PrometheusProtobuf(prometheus_protobuf::LabelKeyEncoder<'a>),
481}
482
483impl<'a> From<text::LabelKeyEncoder<'a>> for LabelKeyEncoder<'a> {
484 fn from(e: text::LabelKeyEncoder<'a>) -> Self {
485 Self(LabelKeyEncoderInner::Text(e))
486 }
487}
488
489#[cfg(feature = "openmetrics_protobuf")]
490impl<'a> From<openmetrics_protobuf::LabelKeyEncoder<'a>> for LabelKeyEncoder<'a> {
491 fn from(e: openmetrics_protobuf::LabelKeyEncoder<'a>) -> Self {
492 Self(LabelKeyEncoderInner::Protobuf(e))
493 }
494}
495
496#[cfg(feature = "prometheus_protobuf")]
497impl<'a> From<prometheus_protobuf::LabelKeyEncoder<'a>> for LabelKeyEncoder<'a> {
498 fn from(e: prometheus_protobuf::LabelKeyEncoder<'a>) -> Self {
499 Self(LabelKeyEncoderInner::PrometheusProtobuf(e))
500 }
501}
502
503impl std::fmt::Write for LabelKeyEncoder<'_> {
504 fn write_str(&mut self, s: &str) -> std::fmt::Result {
505 for_both_mut!(self, LabelKeyEncoderInner, e, e.write_str(s))
506 }
507}
508
509impl<'a> LabelKeyEncoder<'a> {
510 pub fn encode_label_value(self) -> Result<LabelValueEncoder<'a>, std::fmt::Error> {
512 for_both!(
513 self,
514 LabelKeyEncoderInner,
515 e,
516 e.encode_label_value().map(LabelValueEncoder::from)
517 )
518 }
519}
520
521impl EncodeLabelKey for &str {
522 fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error> {
523 encoder.write_str(self)?;
524 Ok(())
525 }
526}
527
528impl EncodeLabelKey for String {
529 fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error> {
530 EncodeLabelKey::encode(&self.as_str(), encoder)
531 }
532}
533
534impl EncodeLabelKey for Cow<'_, str> {
535 fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error> {
536 EncodeLabelKey::encode(&self.as_ref(), encoder)
537 }
538}
539
540impl<T> EncodeLabelKey for Box<T>
541where
542 T: ?Sized,
543 for<'a> &'a T: EncodeLabelKey,
544{
545 fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error> {
546 EncodeLabelKey::encode(&self.as_ref(), encoder)
547 }
548}
549
550impl<T> EncodeLabelKey for Arc<T>
551where
552 T: ?Sized,
553 for<'a> &'a T: EncodeLabelKey,
554{
555 fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error> {
556 EncodeLabelKey::encode(&self.as_ref(), encoder)
557 }
558}
559
560impl<T> EncodeLabelKey for Rc<T>
561where
562 T: ?Sized,
563 for<'a> &'a T: EncodeLabelKey,
564{
565 fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error> {
566 EncodeLabelKey::encode(&self.as_ref(), encoder)
567 }
568}
569
570pub trait EncodeLabelValue {
572 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error>;
574}
575
576#[derive(Debug)]
578pub struct LabelValueEncoder<'a>(LabelValueEncoderInner<'a>);
579
580#[derive(Debug)]
581enum LabelValueEncoderInner<'a> {
582 Text(text::LabelValueEncoder<'a>),
583 #[cfg(feature = "openmetrics_protobuf")]
584 Protobuf(openmetrics_protobuf::LabelValueEncoder<'a>),
585 #[cfg(feature = "prometheus_protobuf")]
586 PrometheusProtobuf(prometheus_protobuf::LabelValueEncoder<'a>),
587}
588
589impl<'a> From<text::LabelValueEncoder<'a>> for LabelValueEncoder<'a> {
590 fn from(e: text::LabelValueEncoder<'a>) -> Self {
591 LabelValueEncoder(LabelValueEncoderInner::Text(e))
592 }
593}
594
595#[cfg(feature = "openmetrics_protobuf")]
596impl<'a> From<openmetrics_protobuf::LabelValueEncoder<'a>> for LabelValueEncoder<'a> {
597 fn from(e: openmetrics_protobuf::LabelValueEncoder<'a>) -> Self {
598 LabelValueEncoder(LabelValueEncoderInner::Protobuf(e))
599 }
600}
601
602#[cfg(feature = "prometheus_protobuf")]
603impl<'a> From<prometheus_protobuf::LabelValueEncoder<'a>> for LabelValueEncoder<'a> {
604 fn from(e: prometheus_protobuf::LabelValueEncoder<'a>) -> Self {
605 LabelValueEncoder(LabelValueEncoderInner::PrometheusProtobuf(e))
606 }
607}
608
609impl std::fmt::Write for LabelValueEncoder<'_> {
610 fn write_str(&mut self, s: &str) -> std::fmt::Result {
611 for_both_mut!(self, LabelValueEncoderInner, e, e.write_str(s))
612 }
613}
614
615impl LabelValueEncoder<'_> {
616 pub(crate) fn write_str_unescaped(&mut self, s: &str) -> Result<(), std::fmt::Error> {
617 for_both_mut!(self, LabelValueEncoderInner, e, e.write_str_unescaped(s))
618 }
619
620 pub fn finish(self) -> Result<(), std::fmt::Error> {
622 for_both!(self, LabelValueEncoderInner, e, e.finish())
623 }
624}
625
626impl EncodeLabelValue for &str {
627 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
628 encoder.write_str(self)?;
629 Ok(())
630 }
631}
632
633impl EncodeLabelValue for String {
634 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
635 EncodeLabelValue::encode(&self.as_str(), encoder)
636 }
637}
638
639impl EncodeLabelValue for &String {
640 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
641 EncodeLabelValue::encode(&self.as_str(), encoder)
642 }
643}
644
645impl EncodeLabelValue for Cow<'_, str> {
646 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
647 EncodeLabelValue::encode(&self.as_ref(), encoder)
648 }
649}
650
651impl<T> EncodeLabelValue for Box<T>
652where
653 T: ?Sized,
654 for<'a> &'a T: EncodeLabelValue,
655{
656 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
657 EncodeLabelValue::encode(&self.as_ref(), encoder)
658 }
659}
660
661impl<T> EncodeLabelValue for Arc<T>
662where
663 T: ?Sized,
664 for<'a> &'a T: EncodeLabelValue,
665{
666 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
667 EncodeLabelValue::encode(&self.as_ref(), encoder)
668 }
669}
670
671impl<T> EncodeLabelValue for Rc<T>
672where
673 T: ?Sized,
674 for<'a> &'a T: EncodeLabelValue,
675{
676 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
677 EncodeLabelValue::encode(&self.as_ref(), encoder)
678 }
679}
680
681impl EncodeLabelValue for f64 {
682 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
683 encoder.write_str_unescaped(dtoa::Buffer::new().format(*self))
684 }
685}
686
687impl<T> EncodeLabelValue for Option<T>
688where
689 T: EncodeLabelValue,
690{
691 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
692 match self {
693 Some(v) => EncodeLabelValue::encode(v, encoder),
694 None => EncodeLabelValue::encode(&"", encoder),
695 }
696 }
697}
698
699impl EncodeLabelValue for bool {
700 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
701 encoder.write_str_unescaped(if *self { "true" } else { "false" })
702 }
703}
704
705macro_rules! impl_encode_label_value_for_integer {
706 ($($t:ident),*) => {$(
707 impl EncodeLabelValue for $t {
708 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
709 encoder.write_str_unescaped(itoa::Buffer::new().format(*self))
710 }
711 }
712 )*};
713}
714
715impl_encode_label_value_for_integer!(
716 u128, i128, u64, i64, u32, i32, u16, i16, u8, i8, usize, isize
717);
718
719pub trait EncodeGaugeValue {
721 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error>;
723}
724
725impl EncodeGaugeValue for u32 {
726 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
727 encoder.encode_u32(*self)
728 }
729}
730
731impl EncodeGaugeValue for i64 {
732 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
733 encoder.encode_i64(*self)
734 }
735}
736
737impl EncodeGaugeValue for u64 {
738 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
739 encoder.encode_u64(*self)
740 }
741}
742
743impl EncodeGaugeValue for isize {
744 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
745 encoder.encode_i64(i64::try_from(*self).map_err(|_err| std::fmt::Error)?)
747 }
748}
749
750impl EncodeGaugeValue for usize {
751 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
752 encoder.encode_i64(i64::try_from(*self).map_err(|_err| std::fmt::Error)?)
755 }
756}
757
758impl EncodeGaugeValue for f64 {
759 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
760 encoder.encode_f64(*self)
761 }
762}
763
764impl EncodeGaugeValue for i32 {
765 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
766 encoder.encode_i64(i64::from(*self))
767 }
768}
769
770impl EncodeGaugeValue for f32 {
771 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
772 encoder.encode_f64(f64::from(*self))
773 }
774}
775
776#[derive(Debug)]
778pub struct GaugeValueEncoder<'a>(GaugeValueEncoderInner<'a>);
779
780#[derive(Debug)]
781enum GaugeValueEncoderInner<'a> {
782 Text(text::GaugeValueEncoder<'a>),
783 #[cfg(feature = "openmetrics_protobuf")]
784 Protobuf(openmetrics_protobuf::GaugeValueEncoder<'a>),
785 #[cfg(feature = "prometheus_protobuf")]
786 PrometheusProtobuf(prometheus_protobuf::GaugeValueEncoder<'a>),
787}
788
789impl GaugeValueEncoder<'_> {
790 fn encode_u32(&mut self, v: u32) -> Result<(), std::fmt::Error> {
791 for_both_mut!(self, GaugeValueEncoderInner, e, e.encode_u32(v))
792 }
793
794 fn encode_u64(&mut self, v: u64) -> Result<(), std::fmt::Error> {
795 for_both_mut!(self, GaugeValueEncoderInner, e, e.encode_u64(v))
796 }
797
798 fn encode_i64(&mut self, v: i64) -> Result<(), std::fmt::Error> {
799 for_both_mut!(self, GaugeValueEncoderInner, e, e.encode_i64(v))
800 }
801
802 fn encode_f64(&mut self, v: f64) -> Result<(), std::fmt::Error> {
803 for_both_mut!(self, GaugeValueEncoderInner, e, e.encode_f64(v))
804 }
805}
806
807impl<'a> From<text::GaugeValueEncoder<'a>> for GaugeValueEncoder<'a> {
808 fn from(e: text::GaugeValueEncoder<'a>) -> Self {
809 GaugeValueEncoder(GaugeValueEncoderInner::Text(e))
810 }
811}
812
813#[cfg(feature = "openmetrics_protobuf")]
814impl<'a> From<openmetrics_protobuf::GaugeValueEncoder<'a>> for GaugeValueEncoder<'a> {
815 fn from(e: openmetrics_protobuf::GaugeValueEncoder<'a>) -> Self {
816 GaugeValueEncoder(GaugeValueEncoderInner::Protobuf(e))
817 }
818}
819
820#[cfg(feature = "prometheus_protobuf")]
821impl<'a> From<prometheus_protobuf::GaugeValueEncoder<'a>> for GaugeValueEncoder<'a> {
822 fn from(e: prometheus_protobuf::GaugeValueEncoder<'a>) -> Self {
823 GaugeValueEncoder(GaugeValueEncoderInner::PrometheusProtobuf(e))
824 }
825}
826
827pub trait EncodeCounterValue {
829 fn encode(&self, encoder: &mut CounterValueEncoder) -> Result<(), std::fmt::Error>;
831}
832
833impl EncodeCounterValue for u64 {
834 fn encode(&self, encoder: &mut CounterValueEncoder) -> Result<(), std::fmt::Error> {
835 encoder.encode_u64(*self)
836 }
837}
838
839impl EncodeCounterValue for usize {
840 fn encode(&self, encoder: &mut CounterValueEncoder) -> Result<(), std::fmt::Error> {
841 encoder.encode_u64(u64::try_from(*self).map_err(|_err| std::fmt::Error)?)
843 }
844}
845
846impl EncodeCounterValue for f64 {
847 fn encode(&self, encoder: &mut CounterValueEncoder) -> Result<(), std::fmt::Error> {
848 encoder.encode_f64(*self)
849 }
850}
851
852impl EncodeCounterValue for u32 {
853 fn encode(&self, encoder: &mut CounterValueEncoder) -> Result<(), std::fmt::Error> {
854 encoder.encode_u64(u64::from(*self))
855 }
856}
857
858impl EncodeCounterValue for f32 {
859 fn encode(&self, encoder: &mut CounterValueEncoder) -> Result<(), std::fmt::Error> {
860 encoder.encode_f64(f64::from(*self))
861 }
862}
863
864#[derive(Debug)]
866pub struct CounterValueEncoder<'a>(CounterValueEncoderInner<'a>);
867
868#[derive(Debug)]
869enum CounterValueEncoderInner<'a> {
870 Text(text::CounterValueEncoder<'a>),
871 #[cfg(feature = "openmetrics_protobuf")]
872 Protobuf(openmetrics_protobuf::CounterValueEncoder<'a>),
873 #[cfg(feature = "prometheus_protobuf")]
874 PrometheusProtobuf(prometheus_protobuf::CounterValueEncoder<'a>),
875}
876
877impl<'a> From<text::CounterValueEncoder<'a>> for CounterValueEncoder<'a> {
878 fn from(e: text::CounterValueEncoder<'a>) -> Self {
879 CounterValueEncoder(CounterValueEncoderInner::Text(e))
880 }
881}
882
883#[cfg(feature = "openmetrics_protobuf")]
884impl<'a> From<openmetrics_protobuf::CounterValueEncoder<'a>> for CounterValueEncoder<'a> {
885 fn from(e: openmetrics_protobuf::CounterValueEncoder<'a>) -> Self {
886 CounterValueEncoder(CounterValueEncoderInner::Protobuf(e))
887 }
888}
889
890#[cfg(feature = "prometheus_protobuf")]
891impl<'a> From<prometheus_protobuf::CounterValueEncoder<'a>> for CounterValueEncoder<'a> {
892 fn from(e: prometheus_protobuf::CounterValueEncoder<'a>) -> Self {
893 CounterValueEncoder(CounterValueEncoderInner::PrometheusProtobuf(e))
894 }
895}
896
897impl CounterValueEncoder<'_> {
898 fn encode_f64(&mut self, v: f64) -> Result<(), std::fmt::Error> {
899 for_both_mut!(self, CounterValueEncoderInner, e, e.encode_f64(v))
900 }
901
902 fn encode_u64(&mut self, v: u64) -> Result<(), std::fmt::Error> {
903 for_both_mut!(self, CounterValueEncoderInner, e, e.encode_u64(v))
904 }
905}
906
907pub trait EncodeExemplarValue {
909 fn encode(&self, encoder: ExemplarValueEncoder) -> Result<(), std::fmt::Error>;
911}
912
913impl EncodeExemplarValue for f64 {
914 fn encode(&self, mut encoder: ExemplarValueEncoder) -> Result<(), std::fmt::Error> {
915 encoder.encode(*self)
916 }
917}
918
919impl EncodeExemplarValue for u64 {
920 fn encode(&self, mut encoder: ExemplarValueEncoder) -> Result<(), std::fmt::Error> {
921 encoder.encode(*self as f64)
922 }
923}
924
925impl EncodeExemplarValue for f32 {
926 fn encode(&self, mut encoder: ExemplarValueEncoder) -> Result<(), std::fmt::Error> {
927 encoder.encode(f64::from(*self))
928 }
929}
930
931impl EncodeExemplarValue for u32 {
932 fn encode(&self, mut encoder: ExemplarValueEncoder) -> Result<(), std::fmt::Error> {
933 encoder.encode(f64::from(*self))
934 }
935}
936
937pub trait EncodeExemplarTime {
939 fn encode(&self, encoder: ExemplarValueEncoder) -> Result<(), std::fmt::Error>;
941}
942
943impl EncodeExemplarTime for SystemTime {
944 fn encode(&self, mut encoder: ExemplarValueEncoder) -> Result<(), std::fmt::Error> {
945 encoder.encode(self.duration_since(UNIX_EPOCH).unwrap().as_secs_f64())
946 }
947}
948
949#[derive(Debug)]
951pub struct ExemplarValueEncoder<'a>(ExemplarValueEncoderInner<'a>);
952
953#[derive(Debug)]
954enum ExemplarValueEncoderInner<'a> {
955 Text(text::ExemplarValueEncoder<'a>),
956 #[cfg(feature = "openmetrics_protobuf")]
957 Protobuf(openmetrics_protobuf::ExemplarValueEncoder<'a>),
958 #[cfg(feature = "prometheus_protobuf")]
959 PrometheusProtobuf(prometheus_protobuf::ExemplarValueEncoder<'a>),
960}
961
962impl<'a> From<text::ExemplarValueEncoder<'a>> for ExemplarValueEncoder<'a> {
963 fn from(e: text::ExemplarValueEncoder<'a>) -> Self {
964 ExemplarValueEncoder(ExemplarValueEncoderInner::Text(e))
965 }
966}
967
968#[cfg(feature = "openmetrics_protobuf")]
969impl<'a> From<openmetrics_protobuf::ExemplarValueEncoder<'a>> for ExemplarValueEncoder<'a> {
970 fn from(e: openmetrics_protobuf::ExemplarValueEncoder<'a>) -> Self {
971 ExemplarValueEncoder(ExemplarValueEncoderInner::Protobuf(e))
972 }
973}
974
975#[cfg(feature = "prometheus_protobuf")]
976impl<'a> From<prometheus_protobuf::ExemplarValueEncoder<'a>> for ExemplarValueEncoder<'a> {
977 fn from(e: prometheus_protobuf::ExemplarValueEncoder<'a>) -> Self {
978 ExemplarValueEncoder(ExemplarValueEncoderInner::PrometheusProtobuf(e))
979 }
980}
981
982impl ExemplarValueEncoder<'_> {
983 fn encode(&mut self, v: f64) -> Result<(), std::fmt::Error> {
984 for_both_mut!(self, ExemplarValueEncoderInner, e, e.encode(v))
985 }
986}