1use std::fmt;
4
5pub use iroh_metrics_derive::Iterable;
13
14use crate::MetricItem;
15
16pub trait Iterable {
18 fn field_count(&self) -> usize;
20 fn field_ref(&self, n: usize) -> Option<MetricItem<'_>>;
22}
23
24pub trait IntoIterable {
26 fn as_iterable(&self) -> &dyn Iterable;
28
29 fn field_iter(&self) -> FieldIter<'_> {
31 FieldIter::new(self.as_iterable())
32 }
33}
34
35impl<T> IntoIterable for T
36where
37 T: Iterable,
38{
39 fn as_iterable(&self) -> &dyn Iterable {
40 self
41 }
42}
43
44pub struct FieldIter<'a> {
48 pos: usize,
49 inner: &'a dyn Iterable,
50}
51
52impl fmt::Debug for FieldIter<'_> {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 write!(f, "FieldIter")
55 }
56}
57
58impl<'a> FieldIter<'a> {
59 pub(crate) fn new(inner: &'a dyn Iterable) -> Self {
60 Self { pos: 0, inner }
61 }
62}
63impl<'a> Iterator for FieldIter<'a> {
64 type Item = MetricItem<'a>;
65
66 fn next(&mut self) -> Option<Self::Item> {
67 if self.pos == self.inner.field_count() {
68 None
69 } else {
70 let out = self.inner.field_ref(self.pos);
71 self.pos += 1;
72 out
73 }
74 }
75
76 fn size_hint(&self) -> (usize, Option<usize>) {
77 let n = self.inner.field_count() - self.pos;
78 (n, Some(n))
79 }
80}