tracing-loki 0.2.1

A tracing layer for shipping logs to Grafana Loki
Documentation
use std::fmt;
use std::ops;
use std::slice;
use tracing_core::Level;

#[derive(Default)]
pub struct LevelMap<T> {
    map: [T; 5],
}

fn level_index(level: Level) -> usize {
    match level {
        Level::TRACE => 0,
        Level::DEBUG => 1,
        Level::INFO => 2,
        Level::WARN => 3,
        Level::ERROR => 4,
    }
}

impl<T> LevelMap<T> {
    pub fn try_from_fn<E, F: FnMut(Level) -> Result<T, E>>(mut f: F) -> Result<LevelMap<T>, E> {
        Ok(LevelMap {
            map: [
                f(Level::TRACE)?,
                f(Level::DEBUG)?,
                f(Level::INFO)?,
                f(Level::WARN)?,
                f(Level::ERROR)?,
            ],
        })
    }
    pub fn values(&self) -> slice::Iter<'_, T> {
        self.map.iter()
    }
    pub fn values_mut(&mut self) -> slice::IterMut<'_, T> {
        self.map.iter_mut()
    }
}

impl<T: fmt::Debug> fmt::Debug for LevelMap<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_map()
            .entry(&Level::TRACE, &self[Level::TRACE])
            .entry(&Level::DEBUG, &self[Level::DEBUG])
            .entry(&Level::INFO, &self[Level::INFO])
            .entry(&Level::WARN, &self[Level::WARN])
            .entry(&Level::ERROR, &self[Level::ERROR])
            .finish()
    }
}

impl<T> ops::Index<Level> for LevelMap<T> {
    type Output = T;
    fn index(&self, index: Level) -> &T {
        &self.map[level_index(index)]
    }
}

impl<T> ops::IndexMut<Level> for LevelMap<T> {
    fn index_mut(&mut self, index: Level) -> &mut T {
        &mut self.map[level_index(index)]
    }
}

struct LevelIter {
    next: Option<Level>,
}

impl Iterator for LevelIter {
    type Item = Level;
    fn next(&mut self) -> Option<Level> {
        let result = self.next;
        self.next = self.next.and_then(|l| {
            Some(match l {
                Level::TRACE => Level::DEBUG,
                Level::DEBUG => Level::INFO,
                Level::INFO => Level::WARN,
                Level::WARN => Level::ERROR,
                Level::ERROR => return None,
            })
        });
        result
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = match self.next {
            Some(Level::TRACE) => 5,
            Some(Level::DEBUG) => 4,
            Some(Level::INFO) => 3,
            Some(Level::WARN) => 2,
            Some(Level::ERROR) => 1,
            None => 0,
        };
        (len, Some(len))
    }
}