1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#[cfg(not(unix))]
use crate::fake_syslog::SyslogNotSupported;
use crate::file::FileLoggerConfig;
use crate::null::NullLoggerConfig;
#[cfg(unix)]
use crate::syslog::SyslogConfig;
use crate::terminal::TerminalLoggerConfig;
use crate::types::Severity;
use crate::{Build, LoggerBuilder, Result};
use serde::{Deserialize, Serialize};
use slog::Logger;

/// Configuration of a logger builder.
pub trait Config {
    /// Logger builder.
    type Builder: Build;

    /// Makes a logger builder associated with this configuration.
    fn try_to_builder(&self) -> Result<Self::Builder>;

    /// Builds a logger with this configuration.
    fn build_logger(&self) -> Result<Logger> {
        let builder = track!(self.try_to_builder())?;
        let logger = track!(builder.build())?;
        Ok(logger)
    }
}

/// The configuration of `LoggerBuilder`.
///
/// # Examples
///
/// Null logger.
///
/// ```
/// extern crate sloggers;
/// extern crate serdeconv;
///
/// use sloggers::LoggerConfig;
///
/// let toml = r#"
/// type = "null"
/// "#;
/// let _config: LoggerConfig = serdeconv::from_toml_str(toml).unwrap();
/// ```
///
/// Terminal logger.
///
/// ```
/// extern crate sloggers;
/// extern crate serdeconv;
///
/// use sloggers::LoggerConfig;
///
/// let toml = r#"
/// type = "terminal"
/// level = "warning"
/// "#;
/// let _config: LoggerConfig = serdeconv::from_toml_str(toml).unwrap();
/// ```
///
/// File logger.
///
/// ```
/// extern crate sloggers;
/// extern crate serdeconv;
///
/// use sloggers::LoggerConfig;
///
/// let toml = r#"
/// type = "file"
/// path = "/path/to/file.log"
/// timezone = "utc"
/// "#;
/// let _config: LoggerConfig = serdeconv::from_toml_str(toml).unwrap();
/// ```
///
/// Syslog logger. (Unix-like systems only.)
///
/// ```
/// extern crate sloggers;
/// extern crate serdeconv;
///
/// use sloggers::LoggerConfig;
///
/// let toml = r#"
/// type = "syslog"
/// facility = "daemon"
/// "#;
/// # #[cfg(unix)]
/// let _config: LoggerConfig = serdeconv::from_toml_str(toml).unwrap();
/// # #[cfg(not(unix))] {
/// #     use std::error::Error as StdError;
/// #     assert!(
/// #         serdeconv::from_toml_str::<LoggerConfig>(toml)
/// #         .expect_err("deserializing the configuration should have failed")
/// #         .to_string()
/// #         .contains("syslog is not supported")
/// #     );
/// # }
/// ```
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
#[serde(rename_all = "lowercase")]
#[non_exhaustive]
pub enum LoggerConfig {
    File(FileLoggerConfig),
    Null(NullLoggerConfig),
    #[cfg(unix)]
    Syslog(SyslogConfig),
    #[cfg(not(unix))]
    #[doc(hidden)]
    Syslog(SyslogNotSupported),
    Terminal(TerminalLoggerConfig),
}
impl LoggerConfig {
    /// Sets the log level of this logger.
    pub fn set_loglevel(&mut self, level: Severity) {
        match *self {
            LoggerConfig::File(ref mut c) => c.level = level,
            LoggerConfig::Null(_) => {}
            #[cfg(unix)]
            LoggerConfig::Syslog(ref mut c) => c.level = level,
            #[cfg(not(unix))]
            LoggerConfig::Syslog(_) => unreachable!(),
            LoggerConfig::Terminal(ref mut c) => c.level = level,
        }
    }
}
impl Config for LoggerConfig {
    type Builder = LoggerBuilder;
    fn try_to_builder(&self) -> Result<Self::Builder> {
        match *self {
            LoggerConfig::File(ref c) => track!(c.try_to_builder()).map(LoggerBuilder::File),
            LoggerConfig::Null(ref c) => track!(c.try_to_builder()).map(LoggerBuilder::Null),
            #[cfg(unix)]
            LoggerConfig::Syslog(ref c) => track!(c.try_to_builder()).map(LoggerBuilder::Syslog),
            #[cfg(not(unix))]
            LoggerConfig::Syslog(_) => unreachable!(),
            LoggerConfig::Terminal(ref c) => {
                track!(c.try_to_builder()).map(LoggerBuilder::Terminal)
            }
        }
    }
}
impl Default for LoggerConfig {
    fn default() -> Self {
        LoggerConfig::Terminal(TerminalLoggerConfig::default())
    }
}