metrics_server 0.16.0

A hassle-free, single-responsibility, safe HTTP/S server used to easily expose metrics in an application.
Documentation
use std::any;
use std::error;
use std::fmt;
use std::io;

/// Errors returned from MetricsServer operations.
#[derive(Debug)]
pub enum Error {
    /// Wraps a standard IO error.
    Io(io::Error),
    /// Represents an error encountered while creating a new server.
    Create(Box<dyn error::Error + Send + Sync + 'static>),
    /// Represents an error due to a panic while stopping the server.
    ShutdownPanicked(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Self::Io(err) => write!(f, "IO error: {err}"),
            Self::Create(err) => write!(f, "error creating metrics server: {err}"),
            Self::ShutdownPanicked(err) => write!(f, "server thread panicked: {err}"),
        }
    }
}

// Handles cause information.
impl error::Error for Error {
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        match self {
            // Forward the source to the inner io::Error
            Self::Io(err) => Some(err),
            // Other variants have no underlying cause
            _ => None,
        }
    }
}

// Handles io errors.
impl From<io::Error> for Error {
    fn from(err: io::Error) -> Self {
        Self::Io(err)
    }
}

// Handles tiny_http errors. Although they are mostly of type std::io::Error,
// there are a few occasions where a generic error is returned, albeit unlikely.
impl From<Box<dyn error::Error + Send + Sync + 'static>> for Error {
    fn from(err: Box<dyn error::Error + Send + Sync + 'static>) -> Self {
        Self::Create(err)
    }
}

// Handles shutdown panic when shutting down.
impl From<Box<dyn any::Any + Send + 'static>> for Error {
    fn from(payload: Box<dyn any::Any + Send + 'static>) -> Self {
        let err = if let Some(s) = payload.downcast_ref::<String>() {
            s.clone()
        } else if let Some(s) = payload.downcast_ref::<&str>() {
            s.to_string()
        } else {
            format!("{:?}", payload)
        };

        Self::ShutdownPanicked(err)
    }
}