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") } } } }