Add 'ConfigError::Missing' to identify missing config keys.

This commit is contained in:
Sergio Benitez 2018-08-14 10:31:54 -07:00
parent d699827079
commit 10f267a56d
3 changed files with 53 additions and 19 deletions

View File

@ -667,11 +667,33 @@ impl Config {
self.secret_key.inner()
}
/// Attempts to retrieve the extra named `name` as a raw value.
///
/// # Errors
///
/// If an extra with `name` doesn't exist, returns an `Err` of `Missing`.
///
/// # Example
///
/// ```rust
/// use rocket::config::{Config, Environment, Value};
///
/// let config = Config::build(Environment::Staging)
/// .extra("name", "value")
/// .unwrap();
///
/// assert_eq!(config.get_extra("name"), Ok(&Value::String("value".into())));
/// assert!(config.get_extra("other").is_err());
/// ```
pub fn get_extra<'a>(&'a self, name: &str) -> Result<&'a Value> {
self.extras.get(name).ok_or_else(|| ConfigError::Missing(name.into()))
}
/// Attempts to retrieve the extra named `name` as a borrowed string.
///
/// # Errors
///
/// If an extra with `name` doesn't exist, returns an `Err` of `NotFound`.
/// If an extra with `name` doesn't exist, returns an `Err` of `Missing`.
/// If an extra with `name` _does_ exist but is not a string, returns a
/// `BadType` error.
///
@ -687,7 +709,7 @@ impl Config {
/// assert_eq!(config.get_str("my_extra"), Ok("extra_value"));
/// ```
pub fn get_str<'a>(&'a self, name: &str) -> Result<&'a str> {
let val = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
let val = self.get_extra(name)?;
val.as_str().ok_or_else(|| self.bad_type(name, val.type_str(), "a string"))
}
@ -695,7 +717,7 @@ impl Config {
///
/// # Errors
///
/// If an extra with `name` doesn't exist, returns an `Err` of `NotFound`.
/// If an extra with `name` doesn't exist, returns an `Err` of `Missing`.
/// If an extra with `name` _does_ exist but is not a string, returns a
/// `BadType` error.
///
@ -718,7 +740,7 @@ impl Config {
///
/// # Errors
///
/// If an extra with `name` doesn't exist, returns an `Err` of `NotFound`.
/// If an extra with `name` doesn't exist, returns an `Err` of `Missing`.
/// If an extra with `name` _does_ exist but is not an integer, returns a
/// `BadType` error.
///
@ -734,7 +756,7 @@ impl Config {
/// assert_eq!(config.get_int("my_extra"), Ok(1025));
/// ```
pub fn get_int(&self, name: &str) -> Result<i64> {
let val = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
let val = self.get_extra(name)?;
val.as_integer().ok_or_else(|| self.bad_type(name, val.type_str(), "an integer"))
}
@ -742,7 +764,7 @@ impl Config {
///
/// # Errors
///
/// If an extra with `name` doesn't exist, returns an `Err` of `NotFound`.
/// If an extra with `name` doesn't exist, returns an `Err` of `Missing`.
/// If an extra with `name` _does_ exist but is not a boolean, returns a
/// `BadType` error.
///
@ -758,7 +780,7 @@ impl Config {
/// assert_eq!(config.get_bool("my_extra"), Ok(true));
/// ```
pub fn get_bool(&self, name: &str) -> Result<bool> {
let val = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
let val = self.get_extra(name)?;
val.as_bool().ok_or_else(|| self.bad_type(name, val.type_str(), "a boolean"))
}
@ -766,7 +788,7 @@ impl Config {
///
/// # Errors
///
/// If an extra with `name` doesn't exist, returns an `Err` of `NotFound`.
/// If an extra with `name` doesn't exist, returns an `Err` of `Missing`.
/// If an extra with `name` _does_ exist but is not a float, returns a
/// `BadType` error.
///
@ -782,7 +804,7 @@ impl Config {
/// assert_eq!(config.get_float("pi"), Ok(3.14159));
/// ```
pub fn get_float(&self, name: &str) -> Result<f64> {
let val = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
let val = self.get_extra(name)?;
val.as_float().ok_or_else(|| self.bad_type(name, val.type_str(), "a float"))
}
@ -790,7 +812,7 @@ impl Config {
///
/// # Errors
///
/// If an extra with `name` doesn't exist, returns an `Err` of `NotFound`.
/// If an extra with `name` doesn't exist, returns an `Err` of `Missing`.
/// If an extra with `name` _does_ exist but is not an array, returns a
/// `BadType` error.
///
@ -806,7 +828,7 @@ impl Config {
/// assert!(config.get_slice("numbers").is_ok());
/// ```
pub fn get_slice(&self, name: &str) -> Result<&Array> {
let val = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
let val = self.get_extra(name)?;
val.as_array().ok_or_else(|| self.bad_type(name, val.type_str(), "an array"))
}
@ -814,7 +836,7 @@ impl Config {
///
/// # Errors
///
/// If an extra with `name` doesn't exist, returns an `Err` of `NotFound`.
/// If an extra with `name` doesn't exist, returns an `Err` of `Missing`.
/// If an extra with `name` _does_ exist but is not a table, returns a
/// `BadType` error.
///
@ -834,7 +856,7 @@ impl Config {
/// assert!(config.get_table("my_table").is_ok());
/// ```
pub fn get_table(&self, name: &str) -> Result<&Table> {
let val = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
let val = self.get_extra(name)?;
val.as_table().ok_or_else(|| self.bad_type(name, val.type_str(), "a table"))
}
@ -842,7 +864,7 @@ impl Config {
///
/// # Errors
///
/// If an extra with `name` doesn't exist, returns an `Err` of `NotFound`.
/// If an extra with `name` doesn't exist, returns an `Err` of `Missing`.
/// If an extra with `name` _does_ exist but is not a datetime, returns a
/// `BadType` error.
///
@ -860,8 +882,9 @@ impl Config {
/// 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"))
let val = self.get_extra(name)?;
val.as_datetime()
.ok_or_else(|| self.bad_type(name, val.type_str(), "a datetime"))
}
/// Returns the path at which the configuration file for `self` is stored.

View File

@ -48,6 +48,10 @@ pub enum ConfigError {
///
/// Parameters: (key)
UnknownKey(String),
/// The entry (key) was expected but was missing.
///
/// Parameters: (key)
Missing(String),
}
impl ConfigError {
@ -101,6 +105,9 @@ impl ConfigError {
error!("the configuration key '{}' is unknown and disallowed in \
this position", White.paint(key));
}
Missing(ref key) => {
error!("missing configuration key: '{}'", White.paint(key));
}
}
}
@ -134,6 +141,7 @@ impl fmt::Display for ConfigError {
BadEnv(ref e) => write!(f, "{:?} is not a valid `ROCKET_ENV` value", e),
ParseError(..) => write!(f, "the config file contains invalid TOML"),
UnknownKey(ref k) => write!(f, "'{}' is an unknown key", k),
Missing(ref k) => write!(f, "missing key: '{}'", k),
BadEntry(ref e, _) => {
write!(f, "{:?} is not a valid `[environment]` entry", e)
}
@ -161,6 +169,7 @@ impl Error for ConfigError {
BadType(..) => "a key was specified with a value of the wrong type",
BadEnvVal(..) => "an environment variable could not be parsed",
UnknownKey(..) => "an unknown key was used in a disallowed position",
Missing(..) => "an expected key was not found",
}
}
}
@ -183,10 +192,11 @@ impl PartialEq for ConfigError {
(&BadEnvVal(ref k1, ref v1, _), &BadEnvVal(ref k2, ref v2, _)) => {
k1 == k2 && v1 == v2
}
(&Missing(ref k1), &Missing(ref k2)) => k1 == k2,
(&BadCWD, _) | (&NotFound, _) | (&IoError, _) | (&Io(..), _)
| (&BadFilePath(..), _) | (&BadEnv(..), _) | (&ParseError(..), _)
| (&UnknownKey(..), _) | (&BadEntry(..), _) | (&BadType(..), _)
| (&BadEnvVal(..), _) => false
| (&BadEnvVal(..), _) | (&Missing(..), _) => false
}
}
}

View File

@ -477,8 +477,9 @@ crate fn init() -> Config {
use self::ConfigError::*;
let config = RocketConfig::read().unwrap_or_else(|e| {
match e {
ParseError(..) | BadEntry(..) | BadEnv(..) | BadType(..) | Io(..)
| BadFilePath(..) | BadEnvVal(..) | UnknownKey(..) => bail(e),
| ParseError(..) | BadEntry(..) | BadEnv(..) | BadType(..) | Io(..)
| BadFilePath(..) | BadEnvVal(..) | UnknownKey(..)
| Missing(..) => bail(e),
IoError | BadCWD => warn!("Failed reading Rocket.toml. Using defaults."),
NotFound => { /* try using the default below */ }
}