1pub use prometheus_client_derive_encode::*;
4
5use crate::metrics::exemplar::Exemplar;
6use crate::metrics::MetricType;
7use crate::registry::{Prefix, Unit};
8use std::borrow::Cow;
9use std::collections::HashMap;
10use std::fmt::Write;
11use std::ops::Deref;
12use std::rc::Rc;
13use std::sync::Arc;
14use std::time::{SystemTime, UNIX_EPOCH};
15
16#[cfg(feature = "protobuf")]
17#[cfg_attr(docsrs, doc(cfg(feature = "protobuf")))]
18pub mod protobuf;
19pub mod text;
20
21macro_rules! for_both_mut {
22 ($self:expr, $inner:ident, $pattern:pat, $fn:expr) => {
23 match &mut $self.0 {
24 $inner::Text($pattern) => $fn,
25 #[cfg(feature = "protobuf")]
26 $inner::Protobuf($pattern) => $fn,
27 }
28 };
29}
30
31macro_rules! for_both {
32 ($self:expr, $inner:ident, $pattern:pat, $fn:expr) => {
33 match $self.0 {
34 $inner::Text($pattern) => $fn,
35 #[cfg(feature = "protobuf")]
36 $inner::Protobuf($pattern) => $fn,
37 }
38 };
39}
40
41pub trait EncodeMetric {
45 fn encode(&self, encoder: MetricEncoder) -> Result<(), std::fmt::Error>;
48
49 fn metric_type(&self) -> MetricType;
53
54 fn is_empty(&self) -> bool {
62 false
63 }
64}
65
66impl EncodeMetric for Box<dyn EncodeMetric> {
67 fn encode(&self, encoder: MetricEncoder) -> Result<(), std::fmt::Error> {
68 self.deref().encode(encoder)
69 }
70
71 fn metric_type(&self) -> MetricType {
72 self.deref().metric_type()
73 }
74}
75
76#[derive(Debug)]
78pub struct DescriptorEncoder<'a>(DescriptorEncoderInner<'a>);
79
80#[derive(Debug)]
81enum DescriptorEncoderInner<'a> {
82 Text(text::DescriptorEncoder<'a>),
83
84 #[cfg(feature = "protobuf")]
85 Protobuf(protobuf::DescriptorEncoder<'a>),
86}
87
88impl<'a> From<text::DescriptorEncoder<'a>> for DescriptorEncoder<'a> {
89 fn from(e: text::DescriptorEncoder<'a>) -> Self {
90 Self(DescriptorEncoderInner::Text(e))
91 }
92}
93
94#[cfg(feature = "protobuf")]
95impl<'a> From<protobuf::DescriptorEncoder<'a>> for DescriptorEncoder<'a> {
96 fn from(e: protobuf::DescriptorEncoder<'a>) -> Self {
97 Self(DescriptorEncoderInner::Protobuf(e))
98 }
99}
100
101impl DescriptorEncoder<'_> {
102 pub(crate) fn with_prefix_and_labels<'s>(
103 &'s mut self,
104 prefix: Option<&'s Prefix>,
105 labels: &'s [(Cow<'static, str>, Cow<'static, str>)],
106 ) -> DescriptorEncoder<'s> {
108 for_both_mut!(
109 self,
110 DescriptorEncoderInner,
111 e,
112 e.with_prefix_and_labels(prefix, labels).into()
113 )
114 }
115
116 pub fn encode_descriptor<'s>(
118 &'s mut self,
119 name: &'s str,
120 help: &str,
121 unit: Option<&'s Unit>,
122 metric_type: MetricType,
123 ) -> Result<MetricEncoder<'s>, std::fmt::Error> {
124 for_both_mut!(
125 self,
126 DescriptorEncoderInner,
127 e,
128 Ok(e.encode_descriptor(name, help, unit, metric_type)?.into())
129 )
130 }
131}
132
133#[derive(Debug)]
135pub struct MetricEncoder<'a>(MetricEncoderInner<'a>);
136
137#[derive(Debug)]
138enum MetricEncoderInner<'a> {
139 Text(text::MetricEncoder<'a>),
140
141 #[cfg(feature = "protobuf")]
142 Protobuf(protobuf::MetricEncoder<'a>),
143}
144
145impl<'a> From<text::MetricEncoder<'a>> for MetricEncoder<'a> {
146 fn from(e: text::MetricEncoder<'a>) -> Self {
147 Self(MetricEncoderInner::Text(e))
148 }
149}
150
151#[cfg(feature = "protobuf")]
152impl<'a> From<protobuf::MetricEncoder<'a>> for MetricEncoder<'a> {
153 fn from(e: protobuf::MetricEncoder<'a>) -> Self {
154 Self(MetricEncoderInner::Protobuf(e))
155 }
156}
157
158impl MetricEncoder<'_> {
159 pub fn encode_counter<
161 S: EncodeLabelSet,
162 CounterValue: EncodeCounterValue,
163 ExemplarValue: EncodeExemplarValue,
164 >(
165 &mut self,
166 v: &CounterValue,
167 exemplar: Option<&Exemplar<S, ExemplarValue>>,
168 ) -> Result<(), std::fmt::Error> {
169 for_both_mut!(self, MetricEncoderInner, e, e.encode_counter(v, exemplar))
170 }
171
172 pub fn encode_gauge<GaugeValue: EncodeGaugeValue>(
174 &mut self,
175 v: &GaugeValue,
176 ) -> Result<(), std::fmt::Error> {
177 for_both_mut!(self, MetricEncoderInner, e, e.encode_gauge(v))
178 }
179
180 pub fn encode_info(&mut self, label_set: &impl EncodeLabelSet) -> Result<(), std::fmt::Error> {
182 for_both_mut!(self, MetricEncoderInner, e, e.encode_info(label_set))
183 }
184
185 pub fn encode_histogram<S: EncodeLabelSet>(
187 &mut self,
188 sum: f64,
189 count: u64,
190 buckets: &[(f64, u64)],
191 exemplars: Option<&HashMap<usize, Exemplar<S, f64>>>,
192 ) -> Result<(), std::fmt::Error> {
193 for_both_mut!(
194 self,
195 MetricEncoderInner,
196 e,
197 e.encode_histogram(sum, count, buckets, exemplars)
198 )
199 }
200
201 pub fn encode_family<'s, S: EncodeLabelSet>(
203 &'s mut self,
204 label_set: &'s S,
205 ) -> Result<MetricEncoder<'s>, std::fmt::Error> {
206 for_both_mut!(
207 self,
208 MetricEncoderInner,
209 e,
210 e.encode_family(label_set).map(Into::into)
211 )
212 }
213}
214
215pub trait EncodeLabelSet {
217 fn encode(&self, encoder: &mut LabelSetEncoder) -> Result<(), std::fmt::Error>;
219}
220
221#[derive(Debug)]
223pub struct LabelSetEncoder<'a>(LabelSetEncoderInner<'a>);
224
225#[derive(Debug)]
226enum LabelSetEncoderInner<'a> {
227 Text(text::LabelSetEncoder<'a>),
228 #[cfg(feature = "protobuf")]
229 Protobuf(protobuf::LabelSetEncoder<'a>),
230}
231
232impl<'a> From<text::LabelSetEncoder<'a>> for LabelSetEncoder<'a> {
233 fn from(e: text::LabelSetEncoder<'a>) -> Self {
234 Self(LabelSetEncoderInner::Text(e))
235 }
236}
237
238#[cfg(feature = "protobuf")]
239impl<'a> From<protobuf::LabelSetEncoder<'a>> for LabelSetEncoder<'a> {
240 fn from(e: protobuf::LabelSetEncoder<'a>) -> Self {
241 Self(LabelSetEncoderInner::Protobuf(e))
242 }
243}
244
245impl LabelSetEncoder<'_> {
246 pub fn encode_label(&mut self) -> LabelEncoder<'_> {
248 for_both_mut!(self, LabelSetEncoderInner, e, e.encode_label().into())
249 }
250}
251
252impl<T: EncodeLabel, const N: usize> EncodeLabelSet for [T; N] {
253 fn encode(&self, encoder: &mut LabelSetEncoder) -> Result<(), std::fmt::Error> {
254 self.as_ref().encode(encoder)
255 }
256}
257
258impl<T: EncodeLabel> EncodeLabelSet for &[T] {
259 fn encode(&self, encoder: &mut LabelSetEncoder) -> Result<(), std::fmt::Error> {
260 if self.is_empty() {
261 return Ok(());
262 }
263
264 for label in self.iter() {
265 let encoder = encoder.encode_label();
266 label.encode(encoder)?
267 }
268
269 Ok(())
270 }
271}
272
273impl<T: EncodeLabel> EncodeLabelSet for Vec<T> {
274 fn encode(&self, encoder: &mut LabelSetEncoder) -> Result<(), std::fmt::Error> {
275 self.as_slice().encode(encoder)
276 }
277}
278
279impl<A, B> EncodeLabelSet for (A, B)
280where
281 A: EncodeLabelSet,
282 B: EncodeLabelSet,
283{
284 fn encode(&self, encoder: &mut LabelSetEncoder) -> Result<(), std::fmt::Error> {
285 let (a, b) = self;
286
287 a.encode(encoder)?;
288 b.encode(encoder)?;
289
290 Ok(())
291 }
292}
293
294#[derive(Debug)]
296pub enum NoLabelSet {}
297
298impl EncodeLabelSet for NoLabelSet {
299 fn encode(&self, _encoder: &mut LabelSetEncoder) -> Result<(), std::fmt::Error> {
300 Ok(())
301 }
302}
303
304pub trait EncodeLabel {
306 fn encode(&self, encoder: LabelEncoder) -> Result<(), std::fmt::Error>;
308}
309
310#[derive(Debug)]
312pub struct LabelEncoder<'a>(LabelEncoderInner<'a>);
313
314#[derive(Debug)]
315enum LabelEncoderInner<'a> {
316 Text(text::LabelEncoder<'a>),
317 #[cfg(feature = "protobuf")]
318 Protobuf(protobuf::LabelEncoder<'a>),
319}
320
321impl<'a> From<text::LabelEncoder<'a>> for LabelEncoder<'a> {
322 fn from(e: text::LabelEncoder<'a>) -> Self {
323 Self(LabelEncoderInner::Text(e))
324 }
325}
326
327#[cfg(feature = "protobuf")]
328impl<'a> From<protobuf::LabelEncoder<'a>> for LabelEncoder<'a> {
329 fn from(e: protobuf::LabelEncoder<'a>) -> Self {
330 Self(LabelEncoderInner::Protobuf(e))
331 }
332}
333
334impl LabelEncoder<'_> {
335 pub fn encode_label_key(&mut self) -> Result<LabelKeyEncoder<'_>, std::fmt::Error> {
337 for_both_mut!(
338 self,
339 LabelEncoderInner,
340 e,
341 e.encode_label_key().map(Into::into)
342 )
343 }
344}
345
346impl<K: EncodeLabelKey, V: EncodeLabelValue> EncodeLabel for (K, V) {
347 fn encode(&self, mut encoder: LabelEncoder) -> Result<(), std::fmt::Error> {
348 let (key, value) = self;
349
350 let mut label_key_encoder = encoder.encode_label_key()?;
351 key.encode(&mut label_key_encoder)?;
352
353 let mut label_value_encoder = label_key_encoder.encode_label_value()?;
354 value.encode(&mut label_value_encoder)?;
355 label_value_encoder.finish()?;
356
357 Ok(())
358 }
359}
360
361pub trait EncodeLabelKey {
363 fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error>;
365}
366
367#[derive(Debug)]
369pub struct LabelKeyEncoder<'a>(LabelKeyEncoderInner<'a>);
370
371#[derive(Debug)]
372enum LabelKeyEncoderInner<'a> {
373 Text(text::LabelKeyEncoder<'a>),
374 #[cfg(feature = "protobuf")]
375 Protobuf(protobuf::LabelKeyEncoder<'a>),
376}
377
378impl<'a> From<text::LabelKeyEncoder<'a>> for LabelKeyEncoder<'a> {
379 fn from(e: text::LabelKeyEncoder<'a>) -> Self {
380 Self(LabelKeyEncoderInner::Text(e))
381 }
382}
383
384#[cfg(feature = "protobuf")]
385impl<'a> From<protobuf::LabelKeyEncoder<'a>> for LabelKeyEncoder<'a> {
386 fn from(e: protobuf::LabelKeyEncoder<'a>) -> Self {
387 Self(LabelKeyEncoderInner::Protobuf(e))
388 }
389}
390
391impl std::fmt::Write for LabelKeyEncoder<'_> {
392 fn write_str(&mut self, s: &str) -> std::fmt::Result {
393 for_both_mut!(self, LabelKeyEncoderInner, e, e.write_str(s))
394 }
395}
396
397impl<'a> LabelKeyEncoder<'a> {
398 pub fn encode_label_value(self) -> Result<LabelValueEncoder<'a>, std::fmt::Error> {
400 for_both!(
401 self,
402 LabelKeyEncoderInner,
403 e,
404 e.encode_label_value().map(LabelValueEncoder::from)
405 )
406 }
407}
408
409impl EncodeLabelKey for &str {
410 fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error> {
411 encoder.write_str(self)?;
412 Ok(())
413 }
414}
415
416impl EncodeLabelKey for String {
417 fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error> {
418 EncodeLabelKey::encode(&self.as_str(), encoder)
419 }
420}
421
422impl EncodeLabelKey for Cow<'_, str> {
423 fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error> {
424 EncodeLabelKey::encode(&self.as_ref(), encoder)
425 }
426}
427
428impl<T> EncodeLabelKey for Box<T>
429where
430 T: ?Sized,
431 for<'a> &'a T: EncodeLabelKey,
432{
433 fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error> {
434 EncodeLabelKey::encode(&self.as_ref(), encoder)
435 }
436}
437
438impl<T> EncodeLabelKey for Arc<T>
439where
440 T: ?Sized,
441 for<'a> &'a T: EncodeLabelKey,
442{
443 fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error> {
444 EncodeLabelKey::encode(&self.as_ref(), encoder)
445 }
446}
447
448impl<T> EncodeLabelKey for Rc<T>
449where
450 T: ?Sized,
451 for<'a> &'a T: EncodeLabelKey,
452{
453 fn encode(&self, encoder: &mut LabelKeyEncoder) -> Result<(), std::fmt::Error> {
454 EncodeLabelKey::encode(&self.as_ref(), encoder)
455 }
456}
457
458pub trait EncodeLabelValue {
460 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error>;
462}
463
464#[derive(Debug)]
466pub struct LabelValueEncoder<'a>(LabelValueEncoderInner<'a>);
467
468#[derive(Debug)]
469enum LabelValueEncoderInner<'a> {
470 Text(text::LabelValueEncoder<'a>),
471 #[cfg(feature = "protobuf")]
472 Protobuf(protobuf::LabelValueEncoder<'a>),
473}
474
475impl<'a> From<text::LabelValueEncoder<'a>> for LabelValueEncoder<'a> {
476 fn from(e: text::LabelValueEncoder<'a>) -> Self {
477 LabelValueEncoder(LabelValueEncoderInner::Text(e))
478 }
479}
480
481#[cfg(feature = "protobuf")]
482impl<'a> From<protobuf::LabelValueEncoder<'a>> for LabelValueEncoder<'a> {
483 fn from(e: protobuf::LabelValueEncoder<'a>) -> Self {
484 LabelValueEncoder(LabelValueEncoderInner::Protobuf(e))
485 }
486}
487
488impl std::fmt::Write for LabelValueEncoder<'_> {
489 fn write_str(&mut self, s: &str) -> std::fmt::Result {
490 for_both_mut!(self, LabelValueEncoderInner, e, e.write_str(s))
491 }
492}
493
494impl LabelValueEncoder<'_> {
495 pub fn finish(self) -> Result<(), std::fmt::Error> {
497 for_both!(self, LabelValueEncoderInner, e, e.finish())
498 }
499}
500
501impl EncodeLabelValue for &str {
502 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
503 encoder.write_str(self)?;
504 Ok(())
505 }
506}
507
508impl EncodeLabelValue for String {
509 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
510 EncodeLabelValue::encode(&self.as_str(), encoder)
511 }
512}
513
514impl EncodeLabelValue for &String {
515 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
516 EncodeLabelValue::encode(&self.as_str(), encoder)
517 }
518}
519
520impl EncodeLabelValue for Cow<'_, str> {
521 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
522 EncodeLabelValue::encode(&self.as_ref(), encoder)
523 }
524}
525
526impl<T> EncodeLabelValue for Box<T>
527where
528 T: ?Sized,
529 for<'a> &'a T: EncodeLabelValue,
530{
531 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
532 EncodeLabelValue::encode(&self.as_ref(), encoder)
533 }
534}
535
536impl<T> EncodeLabelValue for Arc<T>
537where
538 T: ?Sized,
539 for<'a> &'a T: EncodeLabelValue,
540{
541 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
542 EncodeLabelValue::encode(&self.as_ref(), encoder)
543 }
544}
545
546impl<T> EncodeLabelValue for Rc<T>
547where
548 T: ?Sized,
549 for<'a> &'a T: EncodeLabelValue,
550{
551 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
552 EncodeLabelValue::encode(&self.as_ref(), encoder)
553 }
554}
555
556impl EncodeLabelValue for f64 {
557 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
558 encoder.write_str(dtoa::Buffer::new().format(*self))
559 }
560}
561
562impl<T> EncodeLabelValue for Option<T>
563where
564 T: EncodeLabelValue,
565{
566 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
567 match self {
568 Some(v) => EncodeLabelValue::encode(v, encoder),
569 None => EncodeLabelValue::encode(&"", encoder),
570 }
571 }
572}
573
574impl EncodeLabelValue for bool {
575 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
576 encoder.write_str(if *self { "true" } else { "false" })
577 }
578}
579
580macro_rules! impl_encode_label_value_for_integer {
581 ($($t:ident),*) => {$(
582 impl EncodeLabelValue for $t {
583 fn encode(&self, encoder: &mut LabelValueEncoder) -> Result<(), std::fmt::Error> {
584 encoder.write_str(itoa::Buffer::new().format(*self))
585 }
586 }
587 )*};
588}
589
590impl_encode_label_value_for_integer!(
591 u128, i128, u64, i64, u32, i32, u16, i16, u8, i8, usize, isize
592);
593
594pub trait EncodeGaugeValue {
596 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error>;
598}
599
600impl EncodeGaugeValue for u32 {
601 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
602 encoder.encode_u32(*self)
603 }
604}
605
606impl EncodeGaugeValue for i64 {
607 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
608 encoder.encode_i64(*self)
609 }
610}
611
612impl EncodeGaugeValue for u64 {
613 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
614 encoder.encode_i64(i64::try_from(*self).map_err(|_err| std::fmt::Error)?)
618 }
619}
620
621impl EncodeGaugeValue for isize {
622 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
623 encoder.encode_i64(i64::try_from(*self).map_err(|_err| std::fmt::Error)?)
625 }
626}
627
628impl EncodeGaugeValue for usize {
629 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
630 encoder.encode_i64(i64::try_from(*self).map_err(|_err| std::fmt::Error)?)
633 }
634}
635
636impl EncodeGaugeValue for f64 {
637 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
638 encoder.encode_f64(*self)
639 }
640}
641
642impl EncodeGaugeValue for i32 {
643 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
644 encoder.encode_i64(i64::from(*self))
645 }
646}
647
648impl EncodeGaugeValue for f32 {
649 fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
650 encoder.encode_f64(f64::from(*self))
651 }
652}
653
654#[derive(Debug)]
656pub struct GaugeValueEncoder<'a>(GaugeValueEncoderInner<'a>);
657
658#[derive(Debug)]
659enum GaugeValueEncoderInner<'a> {
660 Text(text::GaugeValueEncoder<'a>),
661 #[cfg(feature = "protobuf")]
662 Protobuf(protobuf::GaugeValueEncoder<'a>),
663}
664
665impl GaugeValueEncoder<'_> {
666 fn encode_u32(&mut self, v: u32) -> Result<(), std::fmt::Error> {
667 for_both_mut!(self, GaugeValueEncoderInner, e, e.encode_u32(v))
668 }
669
670 fn encode_i64(&mut self, v: i64) -> Result<(), std::fmt::Error> {
671 for_both_mut!(self, GaugeValueEncoderInner, e, e.encode_i64(v))
672 }
673
674 fn encode_f64(&mut self, v: f64) -> Result<(), std::fmt::Error> {
675 for_both_mut!(self, GaugeValueEncoderInner, e, e.encode_f64(v))
676 }
677}
678
679impl<'a> From<text::GaugeValueEncoder<'a>> for GaugeValueEncoder<'a> {
680 fn from(e: text::GaugeValueEncoder<'a>) -> Self {
681 GaugeValueEncoder(GaugeValueEncoderInner::Text(e))
682 }
683}
684
685#[cfg(feature = "protobuf")]
686impl<'a> From<protobuf::GaugeValueEncoder<'a>> for GaugeValueEncoder<'a> {
687 fn from(e: protobuf::GaugeValueEncoder<'a>) -> Self {
688 GaugeValueEncoder(GaugeValueEncoderInner::Protobuf(e))
689 }
690}
691
692pub trait EncodeCounterValue {
694 fn encode(&self, encoder: &mut CounterValueEncoder) -> Result<(), std::fmt::Error>;
696}
697
698impl EncodeCounterValue for u64 {
699 fn encode(&self, encoder: &mut CounterValueEncoder) -> Result<(), std::fmt::Error> {
700 encoder.encode_u64(*self)
701 }
702}
703
704impl EncodeCounterValue for usize {
705 fn encode(&self, encoder: &mut CounterValueEncoder) -> Result<(), std::fmt::Error> {
706 encoder.encode_u64(u64::try_from(*self).map_err(|_err| std::fmt::Error)?)
708 }
709}
710
711impl EncodeCounterValue for f64 {
712 fn encode(&self, encoder: &mut CounterValueEncoder) -> Result<(), std::fmt::Error> {
713 encoder.encode_f64(*self)
714 }
715}
716
717impl EncodeCounterValue for u32 {
718 fn encode(&self, encoder: &mut CounterValueEncoder) -> Result<(), std::fmt::Error> {
719 encoder.encode_u64(u64::from(*self))
720 }
721}
722
723impl EncodeCounterValue for f32 {
724 fn encode(&self, encoder: &mut CounterValueEncoder) -> Result<(), std::fmt::Error> {
725 encoder.encode_f64(f64::from(*self))
726 }
727}
728
729#[derive(Debug)]
731pub struct CounterValueEncoder<'a>(CounterValueEncoderInner<'a>);
732
733#[derive(Debug)]
734enum CounterValueEncoderInner<'a> {
735 Text(text::CounterValueEncoder<'a>),
736 #[cfg(feature = "protobuf")]
737 Protobuf(protobuf::CounterValueEncoder<'a>),
738}
739
740impl<'a> From<text::CounterValueEncoder<'a>> for CounterValueEncoder<'a> {
741 fn from(e: text::CounterValueEncoder<'a>) -> Self {
742 CounterValueEncoder(CounterValueEncoderInner::Text(e))
743 }
744}
745
746#[cfg(feature = "protobuf")]
747impl<'a> From<protobuf::CounterValueEncoder<'a>> for CounterValueEncoder<'a> {
748 fn from(e: protobuf::CounterValueEncoder<'a>) -> Self {
749 CounterValueEncoder(CounterValueEncoderInner::Protobuf(e))
750 }
751}
752
753impl CounterValueEncoder<'_> {
754 fn encode_f64(&mut self, v: f64) -> Result<(), std::fmt::Error> {
755 for_both_mut!(self, CounterValueEncoderInner, e, e.encode_f64(v))
756 }
757
758 fn encode_u64(&mut self, v: u64) -> Result<(), std::fmt::Error> {
759 for_both_mut!(self, CounterValueEncoderInner, e, e.encode_u64(v))
760 }
761}
762
763pub trait EncodeExemplarValue {
765 fn encode(&self, encoder: ExemplarValueEncoder) -> Result<(), std::fmt::Error>;
767}
768
769impl EncodeExemplarValue for f64 {
770 fn encode(&self, mut encoder: ExemplarValueEncoder) -> Result<(), std::fmt::Error> {
771 encoder.encode(*self)
772 }
773}
774
775impl EncodeExemplarValue for u64 {
776 fn encode(&self, mut encoder: ExemplarValueEncoder) -> Result<(), std::fmt::Error> {
777 encoder.encode(*self as f64)
778 }
779}
780
781impl EncodeExemplarValue for f32 {
782 fn encode(&self, mut encoder: ExemplarValueEncoder) -> Result<(), std::fmt::Error> {
783 encoder.encode(f64::from(*self))
784 }
785}
786
787impl EncodeExemplarValue for u32 {
788 fn encode(&self, mut encoder: ExemplarValueEncoder) -> Result<(), std::fmt::Error> {
789 encoder.encode(f64::from(*self))
790 }
791}
792
793pub trait EncodeExemplarTime {
795 fn encode(&self, encoder: ExemplarValueEncoder) -> Result<(), std::fmt::Error>;
797}
798
799impl EncodeExemplarTime for SystemTime {
800 fn encode(&self, mut encoder: ExemplarValueEncoder) -> Result<(), std::fmt::Error> {
801 encoder.encode(self.duration_since(UNIX_EPOCH).unwrap().as_secs_f64())
802 }
803}
804
805#[derive(Debug)]
807pub struct ExemplarValueEncoder<'a>(ExemplarValueEncoderInner<'a>);
808
809#[derive(Debug)]
810enum ExemplarValueEncoderInner<'a> {
811 Text(text::ExemplarValueEncoder<'a>),
812 #[cfg(feature = "protobuf")]
813 Protobuf(protobuf::ExemplarValueEncoder<'a>),
814}
815
816impl<'a> From<text::ExemplarValueEncoder<'a>> for ExemplarValueEncoder<'a> {
817 fn from(e: text::ExemplarValueEncoder<'a>) -> Self {
818 ExemplarValueEncoder(ExemplarValueEncoderInner::Text(e))
819 }
820}
821
822#[cfg(feature = "protobuf")]
823impl<'a> From<protobuf::ExemplarValueEncoder<'a>> for ExemplarValueEncoder<'a> {
824 fn from(e: protobuf::ExemplarValueEncoder<'a>) -> Self {
825 ExemplarValueEncoder(ExemplarValueEncoderInner::Protobuf(e))
826 }
827}
828
829impl ExemplarValueEncoder<'_> {
830 fn encode(&mut self, v: f64) -> Result<(), std::fmt::Error> {
831 for_both_mut!(self, ExemplarValueEncoderInner, e, e.encode(v))
832 }
833}