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
extern crate fern;
#[macro_use]
extern crate error_chain;
extern crate log;
extern crate toml;

#[cfg(test)]
#[macro_use]
extern crate clams_derive;
#[cfg(test)]
extern crate spectral;
#[cfg(test)]
extern crate serde;
#[cfg(test)]
#[macro_use]
extern crate serde_derive;

pub mod config {
    use std::path::Path;

    trait Config {
        type ConfigStruct;

        fn from_file<T: AsRef<Path>>(file_path: T) -> Result<Self::ConfigStruct>;
    }

    error_chain! {
        errors {
            NoSuchProfile(profile: String) {
                description("No such profile")
                display("No such profile '{}'", profile)
            }
        }
        foreign_links {
            CouldNotRead(::std::io::Error);
            CouldNotParse(::toml::de::Error);
        }
    }

    #[cfg(test)]
    mod test {
        pub use super::*;
        pub use spectral::prelude::*;

        #[derive(Config, Debug, Default, Serialize, Deserialize, PartialEq)]
        struct MyConfig {
            pub general: General,
        }

        #[derive(Debug, Default, Serialize, Deserialize, PartialEq)]
        struct General {
            pub name: String,
        }

        #[test]
        fn read_from_file() {
            let my_config = MyConfig::from_file("examples/my_config.toml");

            assert_that(&my_config).is_ok();
        }
    }
}

pub mod fs {
    use std::path::Path;

    pub fn file_exists<T: AsRef<Path>>(path: T) -> bool {
        path.as_ref().exists()
    }

    #[cfg(test)]
    mod test {
        pub use super::*;
        pub use spectral::prelude::*;

        mod file_exists {
            use super::*;

            #[test]
            fn no_such_file() {
                let file_name = "no_such.file";
                let res = file_exists(&file_name);
                assert_that(&res).is_false();
            }

            #[test]
            fn file_does_exists() {
                let file_name = "tests/data/file.exists";
                let res = file_exists(&file_name);
                assert_that(&res).is_true();
            }
        }
    }
}

pub mod logging {
    use fern;
    use fern::colors::{Color, ColoredLevelConfig};
    use log;
    use std::io;

    pub fn init_logging(internal_mod: &'static str, internal_level: log::LevelFilter, default: log::LevelFilter) -> Result<()> {
        let colors = ColoredLevelConfig::new()
            .info(Color::Green)
            .debug(Color::Blue);
        fern::Dispatch::new()
            .format(move |out, message, record| {
                let level = format!("{}", record.level());
                out.finish(format_args!(
                    "{}{:padding$}{}: {}",
                    colors.color(record.level()),
                    " ",
                    record.target(),
                    message,
                    padding = 6 - level.len(),
                ))
            })
            .chain(
                fern::Dispatch::new()
                    .level(default)
                    .level_for(internal_mod, internal_level)
                    .chain(io::stderr()),
            )
            .apply()
            .map_err(|e| Error::with_chain(e, ErrorKind::FailedToInitLogging))?;

        Ok(())
    }

    pub fn int_to_log_level(n: u64) -> log::LevelFilter {
        match n {
            0 => log::LevelFilter::Warn,
            1 => log::LevelFilter::Info,
            2 => log::LevelFilter::Debug,
            _ => log::LevelFilter::Trace,
        }
    }

    error_chain! {
        errors {
            FailedToInitLogging {
                description("Failed to init logging")
            }
        }
    }
}