Remove 'LoggingLevel' from root. Add ConfigError::Io.

This tentatively completes the 'config' rustdocs.
This commit is contained in:
Sergio Benitez 2017-06-18 21:06:41 -07:00
parent 43a4028085
commit cdf9ff9bde
8 changed files with 114 additions and 48 deletions

View File

@ -175,7 +175,7 @@ macro_rules! register_lints {
pub fn plugin_registrar(reg: &mut Registry) { pub fn plugin_registrar(reg: &mut Registry) {
// Enable logging early if the DEBUG_ENV_VAR is set. // Enable logging early if the DEBUG_ENV_VAR is set.
if env::var(DEBUG_ENV_VAR).is_ok() { if env::var(DEBUG_ENV_VAR).is_ok() {
::rocket::logger::init(::rocket::LoggingLevel::Debug); ::rocket::logger::init(::rocket::config::LoggingLevel::Debug);
} }
reg.register_macro("routes", macros::routes); reg.register_macro("routes", macros::routes);

View File

@ -1,8 +1,7 @@
use rocket::{self, State}; use rocket::{self, State};
use rocket::fairing::AdHoc; use rocket::fairing::AdHoc;
use rocket::config::{self, Config, Environment}; use rocket::config::{self, Config, Environment, LoggingLevel};
use rocket::http::Status; use rocket::http::Status;
use rocket::LoggingLevel;
use rocket::local::Client; use rocket::local::Client;
struct LocalConfig(Config); struct LocalConfig(Config);

View File

@ -1,9 +1,8 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use config::{Result, Config, Value, Environment, Limits}; use config::{Result, Config, Value, Environment, Limits, LoggingLevel};
use config::toml_ext::IntoValue; use config::toml_ext::IntoValue;
use logger::LoggingLevel;
/// Structure following the builder pattern for building `Config` structures. /// Structure following the builder pattern for building `Config` structures.
#[derive(Clone)] #[derive(Clone)]
@ -135,8 +134,7 @@ impl ConfigBuilder {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// use rocket::LoggingLevel; /// use rocket::config::{Config, Environment, LoggingLevel};
/// use rocket::config::{Config, Environment};
/// ///
/// let config = Config::build(Environment::Staging) /// let config = Config::build(Environment::Staging)
/// .log_level(LoggingLevel::Critical) /// .log_level(LoggingLevel::Critical)
@ -155,8 +153,7 @@ impl ConfigBuilder {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// use rocket::LoggingLevel; /// use rocket::config::{Config, Environment, LoggingLevel};
/// use rocket::config::{Config, Environment};
/// ///
/// let key = "8Xui8SN4mI+7egV/9dlfYYLGQJeEx4+DwmSQLwDVXJg="; /// let key = "8Xui8SN4mI+7egV/9dlfYYLGQJeEx4+DwmSQLwDVXJg=";
/// let mut config = Config::build(Environment::Staging) /// let mut config = Config::build(Environment::Staging)
@ -184,7 +181,11 @@ impl ConfigBuilder {
self self
} }
/// Sets the `tls_config` in the configuration being built. /// Sets the TLS configuration in the configuration being built.
///
/// Certificates are read from `certs_path`. The certificate chain must be
/// in X.509 PEM format. The private key is read from `key_path`. The
/// private key must be an RSA key in either PKCS#1 or PKCS#8 PEM format.
/// ///
/// # Example /// # Example
/// ///

View File

@ -8,9 +8,8 @@ use std::env;
use super::custom_values::*; use super::custom_values::*;
use {num_cpus, base64}; use {num_cpus, base64};
use config::Environment::*; use config::Environment::*;
use config::{Result, ConfigBuilder, Environment, ConfigError}; use config::{Result, ConfigBuilder, Environment, ConfigError, LoggingLevel};
use config::{Table, Value, Array, Datetime}; use config::{Table, Value, Array, Datetime};
use logger::LoggingLevel;
use http::Key; use http::Key;
/// Structure for Rocket application configuration. /// Structure for Rocket application configuration.
@ -422,8 +421,7 @@ impl Config {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// use rocket::LoggingLevel; /// use rocket::config::{Config, LoggingLevel, Environment};
/// use rocket::config::{Config, Environment};
/// ///
/// # use rocket::config::ConfigError; /// # use rocket::config::ConfigError;
/// # fn config_test() -> Result<(), ConfigError> { /// # fn config_test() -> Result<(), ConfigError> {
@ -437,31 +435,67 @@ impl Config {
self.log_level = log_level; self.log_level = log_level;
} }
/// Sets limits. /// Set the receive limits in `self` to `limits`.
///
/// # Example
///
/// ```rust
/// use rocket::config::{Config, Limits};
///
/// # use rocket::config::ConfigError;
/// # fn config_test() -> Result<(), ConfigError> {
/// let mut config = Config::development()?;
/// config.set_limits(Limits::default().limit("json", 4 * (1 << 20)));
/// # Ok(())
/// # }
/// ```
#[inline] #[inline]
pub fn set_limits(&mut self, limits: Limits) { pub fn set_limits(&mut self, limits: Limits) {
self.limits = limits; self.limits = limits;
} }
/// Sets the TLS configuration in `self`.
///
/// Certificates are read from `certs_path`. The certificate chain must be
/// in X.509 PEM format. The private key is read from `key_path`. The
/// private key must be an RSA key in either PKCS#1 or PKCS#8 PEM format.
///
/// # Errors
///
/// If reading either the certificates or private key fails, an error of
/// variant `Io` is returned. If either the certificates or private key
/// files are malformed or cannot be parsed, an error of `BadType` is
/// returned.
///
/// # Example
///
/// ```rust
/// use rocket::config::Config;
///
/// # use rocket::config::ConfigError;
/// # fn config_test() -> Result<(), ConfigError> {
/// let mut config = Config::development()?;
/// config.set_tls("/etc/ssl/my_certs.pem", "/etc/ssl/priv.key")?;
/// # Ok(())
/// # }
/// ```
#[cfg(feature = "tls")] #[cfg(feature = "tls")]
pub fn set_tls(&mut self, certs_path: &str, key_path: &str) -> Result<()> { pub fn set_tls(&mut self, certs_path: &str, key_path: &str) -> Result<()> {
use hyper_rustls::util as tls; use hyper_rustls::util as tls;
use hyper_rustls::util::Error::Io; use hyper_rustls::util::Error::Io;
let io_err = "nonexistent or unreadable file";
let pem_err = "malformed PEM file"; let pem_err = "malformed PEM file";
// Load the certificates. // Load the certificates.
let certs = tls::load_certs(certs_path) let certs = tls::load_certs(certs_path)
.map_err(|e| match e { .map_err(|e| match e {
Io(_) => self.bad_type("tls", io_err, "a valid certificates file"), Io(e) => ConfigError::Io(e, "tls"),
_ => self.bad_type("tls", pem_err, "a valid certificates file") _ => self.bad_type("tls", pem_err, "a valid certificates file")
})?; })?;
// And now the private key. // And now the private key.
let key = tls::load_private_key(key_path) let key = tls::load_private_key(key_path)
.map_err(|e| match e { .map_err(|e| match e {
Io(_) => self.bad_type("tls", io_err, "a valid private key file"), Io(e) => ConfigError::Io(e, "tls"),
_ => self.bad_type("tls", pem_err, "a valid private key file") _ => self.bad_type("tls", pem_err, "a valid private key file")
})?; })?;
@ -469,6 +503,7 @@ impl Config {
Ok(()) Ok(())
} }
#[doc(hidden)]
#[cfg(not(feature = "tls"))] #[cfg(not(feature = "tls"))]
pub fn set_tls(&mut self, _: &str, _: &str) -> Result<()> { pub fn set_tls(&mut self, _: &str, _: &str) -> Result<()> {
self.tls = Some(TlsConfig); self.tls = Some(TlsConfig);

View File

@ -2,8 +2,7 @@ use std::fmt;
#[cfg(feature = "tls")] use rustls::{Certificate, PrivateKey}; #[cfg(feature = "tls")] use rustls::{Certificate, PrivateKey};
use logger::LoggingLevel; use config::{Result, Config, Value, ConfigError, LoggingLevel};
use config::{Result, Config, Value, ConfigError};
use http::Key; use http::Key;
#[derive(Clone)] #[derive(Clone)]

View File

@ -1,34 +1,25 @@
use std::path::PathBuf; use std::path::PathBuf;
use std::error::Error; use std::error::Error;
use std::fmt; use std::{io, fmt};
use super::Environment; use super::Environment;
use self::ConfigError::*; use self::ConfigError::*;
use yansi::Color::White; use yansi::Color::White;
/// The type of a configuration parsing error.
#[derive(Debug, PartialEq, Clone)]
pub struct ParsingError {
/// Start and end byte indices into the source code where parsing failed.
pub byte_range: (usize, usize),
/// The (line, column) in the source code where parsing failure began.
pub start: (usize, usize),
/// The (line, column) in the source code where parsing failure ended.
pub end: (usize, usize),
/// A description of the parsing error that occured.
pub desc: String,
}
/// The type of a configuration error. /// The type of a configuration error.
#[derive(Debug, PartialEq, Clone)] #[derive(Debug)]
pub enum ConfigError { pub enum ConfigError {
/// The current working directory could not be determined. /// The current working directory could not be determined.
BadCWD, BadCWD,
/// The configuration file was not found. /// The configuration file was not found.
NotFound, NotFound,
/// There was an I/O error while reading the configuration file. /// There was an I/O error while reading the configuration file.
IOError, IoError,
/// There was an I/O error while setting a configuration parameter.
///
/// Parameters: (io_error, config_param_name)
Io(io::Error, &'static str),
/// The path at which the configuration file was found was invalid. /// The path at which the configuration file was found was invalid.
/// ///
/// Parameters: (path, reason) /// Parameters: (path, reason)
@ -66,7 +57,11 @@ impl ConfigError {
match *self { match *self {
BadCWD => error!("couldn't get current working directory"), BadCWD => error!("couldn't get current working directory"),
NotFound => error!("config file was not found"), NotFound => error!("config file was not found"),
IOError => error!("failed reading the config file: IO error"), IoError => error!("failed reading the config file: IO error"),
Io(ref error, param) => {
error_!("I/O error while setting '{}':", White.paint(param));
info_!("{}", error);
}
BadFilePath(ref path, reason) => { BadFilePath(ref path, reason) => {
error!("configuration file path '{:?}' is invalid", path); error!("configuration file path '{:?}' is invalid", path);
info_!("{}", reason); info_!("{}", reason);
@ -109,7 +104,16 @@ impl ConfigError {
} }
} }
/// Whether this error is of `NotFound` variant. /// Returns `true` if `self` is of `NotFound` variant.
///
/// # Example
///
/// ```rust
/// use rocket::config::ConfigError;
///
/// let error = ConfigError::NotFound;
/// assert!(error.is_not_found());
/// ```
#[inline(always)] #[inline(always)]
pub fn is_not_found(&self) -> bool { pub fn is_not_found(&self) -> bool {
match *self { match *self {
@ -124,7 +128,8 @@ impl fmt::Display for ConfigError {
match *self { match *self {
BadCWD => write!(f, "couldn't get current working directory"), BadCWD => write!(f, "couldn't get current working directory"),
NotFound => write!(f, "config file was not found"), NotFound => write!(f, "config file was not found"),
IOError => write!(f, "I/O error while reading the config file"), IoError => write!(f, "I/O error while reading the config file"),
Io(ref e, p) => write!(f, "I/O error while setting '{}': {}", p, e),
BadFilePath(ref p, _) => write!(f, "{:?} is not a valid config path", p), BadFilePath(ref p, _) => write!(f, "{:?} is not a valid config path", p),
BadEnv(ref e) => write!(f, "{:?} is not a valid `ROCKET_ENV` value", e), BadEnv(ref e) => write!(f, "{:?} is not a valid `ROCKET_ENV` value", e),
ParseError(..) => write!(f, "the config file contains invalid TOML"), ParseError(..) => write!(f, "the config file contains invalid TOML"),
@ -147,7 +152,8 @@ impl Error for ConfigError {
match *self { match *self {
BadCWD => "the current working directory could not be determined", BadCWD => "the current working directory could not be determined",
NotFound => "config file was not found", NotFound => "config file was not found",
IOError => "there was an I/O error while reading the config file", IoError => "there was an I/O error while reading the config file",
Io(..) => "an I/O error occured while setting a configuration parameter",
BadFilePath(..) => "the config file path is invalid", BadFilePath(..) => "the config file path is invalid",
BadEntry(..) => "an environment specified as `[environment]` is invalid", BadEntry(..) => "an environment specified as `[environment]` is invalid",
BadEnv(..) => "the environment specified in `ROCKET_ENV` is invalid", BadEnv(..) => "the environment specified in `ROCKET_ENV` is invalid",
@ -158,3 +164,29 @@ impl Error for ConfigError {
} }
} }
} }
impl PartialEq for ConfigError {
fn eq(&self, other: &ConfigError) -> bool {
match (self, other) {
(&BadCWD, &BadCWD) => true,
(&NotFound, &NotFound) => true,
(&IoError, &IoError) => true,
(&Io(_, p1), &Io(_, p2)) => p1 == p2,
(&BadFilePath(ref p1, _), &BadFilePath(ref p2, _)) => p1 == p2,
(&BadEnv(ref e1), &BadEnv(ref e2)) => e1 == e2,
(&ParseError(..), &ParseError(..)) => true,
(&UnknownKey(ref k1), &UnknownKey(ref k2)) => k1 == k2,
(&BadEntry(ref e1, _), &BadEntry(ref e2, _)) => e1 == e2,
(&BadType(ref n1, e1, a1, _), &BadType(ref n2, e2, a2, _)) => {
n1 == n2 && e1 == e2 && a1 == a2
}
(&BadEnvVal(ref k1, ref v1, _), &BadEnvVal(ref k2, ref v2, _)) => {
k1 == k2 && v1 == v2
}
(&BadCWD, _) | (&NotFound, _) | (&IoError, _) | (&Io(..), _)
| (&BadFilePath(..), _) | (&BadEnv(..), _) | (&ParseError(..), _)
| (&UnknownKey(..), _) | (&BadEntry(..), _) | (&BadType(..), _)
| (&BadEnvVal(..), _) => false
}
}
}

View File

@ -206,17 +206,18 @@ use toml;
pub use self::custom_values::Limits; pub use self::custom_values::Limits;
pub use toml::value::{Array, Table, Value, Datetime}; pub use toml::value::{Array, Table, Value, Datetime};
pub use self::error::{ConfigError, ParsingError}; pub use self::error::ConfigError;
pub use self::environment::Environment; pub use self::environment::Environment;
pub use self::config::Config; pub use self::config::Config;
pub use self::builder::ConfigBuilder; pub use self::builder::ConfigBuilder;
pub use self::toml_ext::IntoValue; pub use self::toml_ext::IntoValue;
pub use logger::LoggingLevel;
pub(crate) use self::toml_ext::LoggedValue; pub(crate) use self::toml_ext::LoggedValue;
use logger;
use self::Environment::*; use self::Environment::*;
use self::environment::CONFIG_ENV; use self::environment::CONFIG_ENV;
use self::toml_ext::parse_simple_toml_value; use self::toml_ext::parse_simple_toml_value;
use logger::{self, LoggingLevel};
use http::uncased::uncased_eq; use http::uncased::uncased_eq;
const CONFIG_FILENAME: &'static str = "Rocket.toml"; const CONFIG_FILENAME: &'static str = "Rocket.toml";
@ -269,11 +270,11 @@ impl RocketConfig {
let file = RocketConfig::find()?; let file = RocketConfig::find()?;
// Try to open the config file for reading. // Try to open the config file for reading.
let mut handle = File::open(&file).map_err(|_| ConfigError::IOError)?; let mut handle = File::open(&file).map_err(|_| ConfigError::IoError)?;
// Read the configure file to a string for parsing. // Read the configure file to a string for parsing.
let mut contents = String::new(); let mut contents = String::new();
handle.read_to_string(&mut contents).map_err(|_| ConfigError::IOError)?; handle.read_to_string(&mut contents).map_err(|_| ConfigError::IoError)?;
// Parse the config and return the result. // Parse the config and return the result.
RocketConfig::parse(contents, &file) RocketConfig::parse(contents, &file)
@ -474,9 +475,9 @@ pub(crate) fn init() -> Config {
use self::ConfigError::*; use self::ConfigError::*;
let config = RocketConfig::read().unwrap_or_else(|e| { let config = RocketConfig::read().unwrap_or_else(|e| {
match e { match e {
ParseError(..) | BadEntry(..) | BadEnv(..) | BadType(..) ParseError(..) | BadEntry(..) | BadEnv(..) | BadType(..) | Io(..)
| BadFilePath(..) | BadEnvVal(..) | UnknownKey(..) => bail(e), | BadFilePath(..) | BadEnvVal(..) | UnknownKey(..) => bail(e),
IOError | BadCWD => warn!("Failed reading Rocket.toml. Using defaults."), IoError | BadCWD => warn!("Failed reading Rocket.toml. Using defaults."),
NotFound => { /* try using the default below */ } NotFound => { /* try using the default below */ }
} }

View File

@ -139,7 +139,6 @@ mod ext;
#[doc(inline)] pub use response::Response; #[doc(inline)] pub use response::Response;
#[doc(inline)] pub use handler::{Handler, ErrorHandler}; #[doc(inline)] pub use handler::{Handler, ErrorHandler};
#[doc(inline)] pub use logger::LoggingLevel;
#[doc(hidden)] pub use codegen::{StaticRouteInfo, StaticCatchInfo}; #[doc(hidden)] pub use codegen::{StaticRouteInfo, StaticCatchInfo};
#[doc(inline)] pub use outcome::Outcome; #[doc(inline)] pub use outcome::Outcome;
#[doc(inline)] pub use data::Data; #[doc(inline)] pub use data::Data;