From cdf9ff9bde569c311afdd3cf62dd560d4251ad75 Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Sun, 18 Jun 2017 21:06:41 -0700 Subject: [PATCH] Remove 'LoggingLevel' from root. Add ConfigError::Io. This tentatively completes the 'config' rustdocs. --- codegen/src/lib.rs | 2 +- examples/config/tests/common/mod.rs | 3 +- lib/src/config/builder.rs | 15 +++--- lib/src/config/config.rs | 53 +++++++++++++++++---- lib/src/config/custom_values.rs | 3 +- lib/src/config/error.rs | 72 +++++++++++++++++++++-------- lib/src/config/mod.rs | 13 +++--- lib/src/lib.rs | 1 - 8 files changed, 114 insertions(+), 48 deletions(-) diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 1be81f2e..5caa0899 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -175,7 +175,7 @@ macro_rules! register_lints { pub fn plugin_registrar(reg: &mut Registry) { // Enable logging early if the DEBUG_ENV_VAR is set. 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); diff --git a/examples/config/tests/common/mod.rs b/examples/config/tests/common/mod.rs index 5eb8f5f3..b5d11742 100644 --- a/examples/config/tests/common/mod.rs +++ b/examples/config/tests/common/mod.rs @@ -1,8 +1,7 @@ use rocket::{self, State}; use rocket::fairing::AdHoc; -use rocket::config::{self, Config, Environment}; +use rocket::config::{self, Config, Environment, LoggingLevel}; use rocket::http::Status; -use rocket::LoggingLevel; use rocket::local::Client; struct LocalConfig(Config); diff --git a/lib/src/config/builder.rs b/lib/src/config/builder.rs index 3e43bae5..932288d6 100644 --- a/lib/src/config/builder.rs +++ b/lib/src/config/builder.rs @@ -1,9 +1,8 @@ use std::collections::HashMap; 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 logger::LoggingLevel; /// Structure following the builder pattern for building `Config` structures. #[derive(Clone)] @@ -135,8 +134,7 @@ impl ConfigBuilder { /// # Example /// /// ```rust - /// use rocket::LoggingLevel; - /// use rocket::config::{Config, Environment}; + /// use rocket::config::{Config, Environment, LoggingLevel}; /// /// let config = Config::build(Environment::Staging) /// .log_level(LoggingLevel::Critical) @@ -155,8 +153,7 @@ impl ConfigBuilder { /// # Example /// /// ```rust - /// use rocket::LoggingLevel; - /// use rocket::config::{Config, Environment}; + /// use rocket::config::{Config, Environment, LoggingLevel}; /// /// let key = "8Xui8SN4mI+7egV/9dlfYYLGQJeEx4+DwmSQLwDVXJg="; /// let mut config = Config::build(Environment::Staging) @@ -184,7 +181,11 @@ impl ConfigBuilder { 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 /// diff --git a/lib/src/config/config.rs b/lib/src/config/config.rs index 9a5c6601..ee8ad605 100644 --- a/lib/src/config/config.rs +++ b/lib/src/config/config.rs @@ -8,9 +8,8 @@ use std::env; use super::custom_values::*; use {num_cpus, base64}; use config::Environment::*; -use config::{Result, ConfigBuilder, Environment, ConfigError}; +use config::{Result, ConfigBuilder, Environment, ConfigError, LoggingLevel}; use config::{Table, Value, Array, Datetime}; -use logger::LoggingLevel; use http::Key; /// Structure for Rocket application configuration. @@ -422,8 +421,7 @@ impl Config { /// # Example /// /// ```rust - /// use rocket::LoggingLevel; - /// use rocket::config::{Config, Environment}; + /// use rocket::config::{Config, LoggingLevel, Environment}; /// /// # use rocket::config::ConfigError; /// # fn config_test() -> Result<(), ConfigError> { @@ -437,31 +435,67 @@ impl Config { 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] pub fn set_limits(&mut 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")] pub fn set_tls(&mut self, certs_path: &str, key_path: &str) -> Result<()> { use hyper_rustls::util as tls; use hyper_rustls::util::Error::Io; - - let io_err = "nonexistent or unreadable file"; let pem_err = "malformed PEM file"; // Load the certificates. let certs = tls::load_certs(certs_path) .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") })?; // And now the private key. let key = tls::load_private_key(key_path) .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") })?; @@ -469,6 +503,7 @@ impl Config { Ok(()) } + #[doc(hidden)] #[cfg(not(feature = "tls"))] pub fn set_tls(&mut self, _: &str, _: &str) -> Result<()> { self.tls = Some(TlsConfig); diff --git a/lib/src/config/custom_values.rs b/lib/src/config/custom_values.rs index 5c590590..42727c30 100644 --- a/lib/src/config/custom_values.rs +++ b/lib/src/config/custom_values.rs @@ -2,8 +2,7 @@ use std::fmt; #[cfg(feature = "tls")] use rustls::{Certificate, PrivateKey}; -use logger::LoggingLevel; -use config::{Result, Config, Value, ConfigError}; +use config::{Result, Config, Value, ConfigError, LoggingLevel}; use http::Key; #[derive(Clone)] diff --git a/lib/src/config/error.rs b/lib/src/config/error.rs index 51bc31c1..df156f70 100644 --- a/lib/src/config/error.rs +++ b/lib/src/config/error.rs @@ -1,34 +1,25 @@ use std::path::PathBuf; use std::error::Error; -use std::fmt; +use std::{io, fmt}; use super::Environment; use self::ConfigError::*; 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. -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug)] pub enum ConfigError { /// The current working directory could not be determined. BadCWD, /// The configuration file was not found. NotFound, /// 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. /// /// Parameters: (path, reason) @@ -66,7 +57,11 @@ impl ConfigError { match *self { BadCWD => error!("couldn't get current working directory"), 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) => { error!("configuration file path '{:?}' is invalid", path); 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)] pub fn is_not_found(&self) -> bool { match *self { @@ -124,7 +128,8 @@ impl fmt::Display for ConfigError { match *self { BadCWD => write!(f, "couldn't get current working directory"), 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), BadEnv(ref e) => write!(f, "{:?} is not a valid `ROCKET_ENV` value", e), ParseError(..) => write!(f, "the config file contains invalid TOML"), @@ -147,7 +152,8 @@ impl Error for ConfigError { match *self { BadCWD => "the current working directory could not be determined", 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", BadEntry(..) => "an environment specified as `[environment]` 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 + } + } +} diff --git a/lib/src/config/mod.rs b/lib/src/config/mod.rs index 68b5714d..657cf77d 100644 --- a/lib/src/config/mod.rs +++ b/lib/src/config/mod.rs @@ -206,17 +206,18 @@ use toml; pub use self::custom_values::Limits; 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::config::Config; pub use self::builder::ConfigBuilder; pub use self::toml_ext::IntoValue; +pub use logger::LoggingLevel; pub(crate) use self::toml_ext::LoggedValue; +use logger; use self::Environment::*; use self::environment::CONFIG_ENV; use self::toml_ext::parse_simple_toml_value; -use logger::{self, LoggingLevel}; use http::uncased::uncased_eq; const CONFIG_FILENAME: &'static str = "Rocket.toml"; @@ -269,11 +270,11 @@ impl RocketConfig { let file = RocketConfig::find()?; // 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. 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. RocketConfig::parse(contents, &file) @@ -474,9 +475,9 @@ pub(crate) fn init() -> Config { use self::ConfigError::*; let config = RocketConfig::read().unwrap_or_else(|e| { match e { - ParseError(..) | BadEntry(..) | BadEnv(..) | BadType(..) + ParseError(..) | BadEntry(..) | BadEnv(..) | BadType(..) | Io(..) | 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 */ } } diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 66c29179..61b55888 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -139,7 +139,6 @@ mod ext; #[doc(inline)] pub use response::Response; #[doc(inline)] pub use handler::{Handler, ErrorHandler}; -#[doc(inline)] pub use logger::LoggingLevel; #[doc(hidden)] pub use codegen::{StaticRouteInfo, StaticCatchInfo}; #[doc(inline)] pub use outcome::Outcome; #[doc(inline)] pub use data::Data;