clap-logflag 0.2.1

This library can be used to add a `--log` flag to clap based command line applications that allows users to configure logging from the command line. It can log to stderr, files and syslog, powered by the fern logging backend.
Documentation
use std::path::PathBuf;

/// This enum represents the whole logging configuration,
/// including all logging destinations and their respective log level filters.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LoggingConfig {
    /// List of destinations to log to.
    /// If the list of destinations is empty, logging is disabled.
    destinations: Vec<LogDestinationConfig>,
}

impl LoggingConfig {
    /// Create a new [LoggingConfig] with the given destinations.
    ///
    /// If the list of destinations is empty, logging is disabled.
    pub fn new(destinations: Vec<LogDestinationConfig>) -> Self {
        Self { destinations }
    }

    /// Create a [LoggingConfig] that disables logging.
    pub fn disabled() -> Self {
        Self {
            destinations: vec![],
        }
    }

    /// Get the list of destinations to log to.
    pub fn destinations(&self) -> &[LogDestinationConfig] {
        &self.destinations
    }
}

/// Configuration for a log destination, containing the destination and the log level.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LogDestinationConfig {
    /// The destination to log to.
    pub destination: LogDestination,

    /// Only log messages at this level or higher to this destination.
    ///
    /// If `None`, the default level is used.
    pub level: Option<log::LevelFilter>,
}

/// A destination that can be logged to, e.g. a file or the system log.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum LogDestination {
    /// Log to stderr
    Stderr,

    /// Log to the file at the given path
    File(PathBuf),

    /// Log to the system log
    Syslog,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn disabled() {
        let config = LoggingConfig::disabled();
        assert!(config.destinations().is_empty());
    }

    #[test]
    fn new() {
        let config = LoggingConfig::new(vec![
            LogDestinationConfig {
                destination: LogDestination::Stderr,
                level: Some(log::LevelFilter::Info),
            },
            LogDestinationConfig {
                destination: LogDestination::File(PathBuf::from("/tmp/logfile")),
                level: Some(log::LevelFilter::Debug),
            },
        ]);
        assert_eq!(
            vec![
                LogDestinationConfig {
                    destination: LogDestination::Stderr,
                    level: Some(log::LevelFilter::Info),
                },
                LogDestinationConfig {
                    destination: LogDestination::File(PathBuf::from("/tmp/logfile")),
                    level: Some(log::LevelFilter::Debug),
                },
            ],
            config.destinations()
        );
    }
}