Update toml to 0.4. Add Config::get_datetime.

This commit is contained in:
Sergio Benitez 2017-06-11 02:20:57 -07:00
parent 2bfb41d968
commit 8badc73c4b
5 changed files with 81 additions and 41 deletions

View File

@ -21,7 +21,7 @@ tls = ["rustls", "hyper-rustls"]
yansi = "0.3"
log = "0.3"
url = "1"
toml = { version = "0.2", default-features = false }
toml = "0.4"
num_cpus = "1"
state = "0.2.2"
time = "0.1"

View File

@ -319,7 +319,7 @@ impl ConfigBuilder {
/// # Panics
///
/// Panics if the current working directory cannot be retrieved or if the
/// supplied address or secret key fail to parse.
/// supplied address, secret key, or TLS configuration fail to parse.
///
/// # Example
///
@ -336,4 +336,29 @@ impl ConfigBuilder {
pub fn unwrap(self) -> Config {
self.finalize().expect("ConfigBuilder::unwrap() failed")
}
///
/// Returns the `Config` structure that was being built by this builder.
///
/// # Panics
///
/// Panics if the current working directory cannot be retrieved or if the
/// supplied address, secret key, or TLS configuration fail to parse. If a
/// panic occurs, the error message `msg` is printed.
///
/// # Example
///
/// ```rust
/// use rocket::config::{Config, Environment};
///
/// let config = Config::build(Environment::Staging)
/// .address("127.0.0.1")
/// .expect("the configuration is bad!");
///
/// assert_eq!(config.address.as_str(), "127.0.0.1");
/// ```
#[inline(always)]
pub fn expect(self, msg: &str) -> Config {
self.finalize().expect(msg)
}
}

View File

@ -8,7 +8,8 @@ use std::env;
use super::custom_values::*;
use {num_cpus, base64};
use config::Environment::*;
use config::{Result, Table, Value, ConfigBuilder, Environment, ConfigError};
use config::{Result, ConfigBuilder, Environment, ConfigError};
use config::{Table, Value, Array, Datetime};
use logger::LoggingLevel;
use http::Key;
@ -662,9 +663,9 @@ impl Config {
///
/// assert!(config.get_slice("numbers").is_ok());
/// ```
pub fn get_slice(&self, name: &str) -> Result<&[Value]> {
pub fn get_slice(&self, name: &str) -> Result<&Array> {
let val = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
val.as_slice().ok_or_else(|| self.bad_type(name, val.type_str(), "a slice"))
val.as_array().ok_or_else(|| self.bad_type(name, val.type_str(), "an array"))
}
/// Attempts to retrieve the extra named `name` as a table.
@ -695,6 +696,32 @@ impl Config {
val.as_table().ok_or_else(|| self.bad_type(name, val.type_str(), "a table"))
}
/// Attempts to retrieve the extra named `name` as a datetime value.
///
/// # Errors
///
/// If an extra with `name` doesn't exist, returns an `Err` of `NotFound`.
/// If an extra with `name` _does_ exist but is not a datetime, returns a
/// `BadType` error.
///
/// # Example
///
/// ```rust
/// use rocket::config::{Config, Environment, Value, Datetime};
///
/// let date = "1979-05-27T00:32:00-07:00".parse::<Datetime>().unwrap();
///
/// let config = Config::build(Environment::Staging)
/// .extra("my_date", Value::Datetime(date.clone()))
/// .unwrap();
///
/// assert_eq!(config.get_datetime("my_date"), Ok(&date));
/// ```
pub fn get_datetime(&self, name: &str) -> Result<&Datetime> {
let v = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
v.as_datetime().ok_or_else(|| self.bad_type(name, v.type_str(), "a datetime"))
}
/// Returns the path at which the configuration file for `self` is stored.
/// For instance, if the configuration file is at `/tmp/Rocket.toml`, the
/// path `/tmp` is returned.
@ -721,7 +748,8 @@ impl Config {
impl fmt::Debug for Config {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Config[{}] {{ address: {}, port: {}, workers: {}, log: {:?}",
self.environment, self.address, self.port, self.workers, self.log_level)?;
self.environment, self.address, self.port, self.workers,
self.log_level)?;
for (key, value) in self.extras() {
write!(f, ", {}: {}", key, value)?;

View File

@ -47,8 +47,8 @@ pub enum ConfigError {
BadType(String, &'static str, &'static str, PathBuf),
/// There was a TOML parsing error.
///
/// Parameters: (toml_source_string, filename, error_list)
ParseError(String, PathBuf, Vec<ParsingError>),
/// Parameters: (toml_source_string, filename, error_description, line/col)
ParseError(String, PathBuf, String, Option<(usize, usize)>),
/// There was a TOML parsing error in a config environment variable.
///
/// Parameters: (env_key, env_value, error)
@ -87,15 +87,14 @@ impl ConfigError {
info_!("expected value to be {}, but found {}",
White.paint(expected), White.paint(actual));
}
ParseError(ref source, ref filename, ref errors) => {
for error in errors {
let (lo, hi) = error.byte_range;
let (line, col) = error.start;
let error_source = &source[lo..hi];
error!("config file failed to parse due to invalid TOML");
info_!("at {:?}:{}:{}", White.paint(filename), line + 1, col + 1);
trace_!("{:?} - {}", error_source, White.paint(&error.desc));
ParseError(_, ref filename, ref desc, line_col) => {
error!("config file failed to parse due to invalid TOML");
info_!("{}", desc);
if let Some((line, col)) = line_col {
info_!("at {:?}:{}:{}", White.paint(filename),
White.paint(line + 1), White.paint(col + 1));
} else {
info_!("in {:?}", White.paint(filename));
}
}
BadEnvVal(ref key, ref value, ref error) => {

View File

@ -203,7 +203,7 @@ use std::env;
use toml;
pub use self::custom_values::Limits;
pub use toml::{Array, Table, Value};
pub use toml::value::{Array, Table, Value, Datetime};
pub use self::error::{ConfigError, ParsingError};
pub use self::environment::Environment;
pub use self::config::Config;
@ -391,30 +391,18 @@ impl RocketConfig {
/// Parses the configuration from the Rocket.toml file. Also overrides any
/// values there with values from the environment.
fn parse<P: AsRef<Path>>(src: String, filename: P) -> Result<RocketConfig> {
// Get a PathBuf version of the filename.
let path = filename.as_ref().to_path_buf();
use self::ConfigError::ParseError;
// Parse the source as TOML, if possible.
let mut parser = toml::Parser::new(&src);
let toml = parser.parse().ok_or_else(|| {
let source = src.clone();
let errors = parser.errors.iter()
.map(|error| {
// workaround for poor error messages `toml`
let debug_desc = format!("{:?}", error.desc);
// strip the leading " and trailing " from debug formatting
let desc = debug_desc[1..debug_desc.len() - 1].to_string();
ParsingError {
byte_range: (error.lo, error.hi),
start: parser.to_linecol(error.lo),
end: parser.to_linecol(error.hi),
desc: desc
}
});
ConfigError::ParseError(source, path.clone(), errors.collect())
})?;
let path = filename.as_ref().to_path_buf();
let table = match src.parse::<toml::Value>() {
Ok(toml::Value::Table(table)) => table,
Ok(value) => {
let err = format!("expected a table, found {}", value.type_str());
return Err(ConfigError::ParseError(src, path, err, Some((1, 1))));
}
Err(e) => return Err(ParseError(src, path, e.to_string(), e.line_col()))
};
// Create a config with the defaults; set the env to the active one.
let mut config = RocketConfig::active_default(filename)?;
@ -423,7 +411,7 @@ impl RocketConfig {
let mut global = None;
// Parse the values from the TOML file.
for (entry, value) in toml {
for (entry, value) in table {
// Each environment must be a table.
let kv_pairs = match value.as_table() {
Some(table) => table,