use std::iter::FusedIterator;
use crate::{dynmetrics, metric, MetricEntry};
used_in_docs!(metric, dynmetrics);
pub fn metrics() -> Metrics {
Metrics(metriken_core::metrics())
}
pub struct Metrics(metriken_core::Metrics);
impl Metrics {
pub fn static_metrics(&self) -> &'static [MetricEntry] {
unsafe { std::mem::transmute(self.0.static_metrics()) }
}
pub fn dynamic_metrics(&self) -> DynMetricsIter {
DynMetricsIter(self.0.dynamic_metrics())
}
pub fn iter(&self) -> MetricsIter {
self.into_iter()
}
}
impl<'a> IntoIterator for &'a Metrics {
type Item = &'a MetricEntry;
type IntoIter = MetricsIter<'a>;
fn into_iter(self) -> Self::IntoIter {
MetricsIter::new(self.static_metrics(), self.dynamic_metrics())
}
}
pub struct MetricsIter<'a> {
sm: std::slice::Iter<'a, MetricEntry>,
dm: DynMetricsIter<'a>,
}
impl<'a> MetricsIter<'a> {
fn new(sm: &'a [MetricEntry], dm: DynMetricsIter<'a>) -> Self {
Self { sm: sm.iter(), dm }
}
}
impl<'a> Iterator for MetricsIter<'a> {
type Item = &'a MetricEntry;
fn next(&mut self) -> Option<Self::Item> {
self.sm.next().or_else(|| self.dm.next())
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (slo, shi) = self.sm.size_hint();
let (dlo, dhi) = self.sm.size_hint();
match (shi, dhi) {
(Some(shi), Some(dhi)) => (slo.saturating_add(dlo), shi.checked_add(dhi)),
_ => (slo.saturating_add(dlo), None),
}
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let len = self.sm.len();
self.sm.nth(n).or_else(|| self.dm.nth(n - len))
}
fn count(self) -> usize
where
Self: Sized,
{
self.sm.count() + self.dm.count()
}
fn fold<B, F>(self, init: B, mut f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
let init = self.sm.fold(init, &mut f);
self.dm.fold(init, f)
}
}
impl<'a> DoubleEndedIterator for MetricsIter<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
self.dm.next_back().or_else(|| self.sm.next_back())
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let len = self.dm.len();
self.dm.nth_back(n).or_else(|| self.dm.nth_back(n - len))
}
fn rfold<B, F>(self, init: B, mut f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
let init = self.dm.rfold(init, &mut f);
self.sm.rfold(init, f)
}
}
impl<'a> FusedIterator for MetricsIter<'a> {}
pub struct DynMetricsIter<'a>(metriken_core::DynMetricsIter<'a>);
impl<'a> Iterator for DynMetricsIter<'a> {
type Item = &'a MetricEntry;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(MetricEntry::from_core)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.0.nth(n).map(MetricEntry::from_core)
}
fn count(self) -> usize
where
Self: Sized,
{
self.0.count()
}
fn fold<B, F>(self, init: B, mut f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
self.0
.fold(init, |accum, item| f(accum, MetricEntry::from_core(item)))
}
}
impl<'a> DoubleEndedIterator for DynMetricsIter<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back().map(MetricEntry::from_core)
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.0.nth_back(n).map(MetricEntry::from_core)
}
fn rfold<B, F>(self, init: B, mut f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
self.0
.rfold(init, |accum, item| f(accum, MetricEntry::from_core(item)))
}
}
impl<'a> ExactSizeIterator for DynMetricsIter<'a> {}
impl<'a> FusedIterator for DynMetricsIter<'a> {}