mirror of https://github.com/rwf2/Rocket.git
Remove the need for a current working directory.
This commit includes several breaking changes: * `Config{new,development,staging,production}` constructors return a `Config` instead of a `Result<Config>`. * `Config.root()` returns an `Option<&Path>` instead of `&Path`. * `ConfigError::BadCWD` was removed. * `Config` no longer exposes a `config_path` field. Resolves #809.
This commit is contained in:
parent
4dea9eed36
commit
834c91ae9d
|
@ -26,21 +26,16 @@ pub struct ConfigBuilder {
|
|||
pub limits: Limits,
|
||||
/// Any extra parameters that aren't part of Rocket's config.
|
||||
pub extras: HashMap<String, Value>,
|
||||
/// The root directory of this config.
|
||||
pub root: PathBuf,
|
||||
/// The root directory of this config, if any.
|
||||
pub root: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl ConfigBuilder {
|
||||
/// Create a new `ConfigBuilder` instance using the default parameters from
|
||||
/// the given `environment`. The root configuration directory is set to the
|
||||
/// current working directory.
|
||||
/// the given `environment`.
|
||||
///
|
||||
/// This method is typically called indirectly via [`Config::build()`].
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the current directory cannot be retrieved.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
|
@ -55,10 +50,7 @@ impl ConfigBuilder {
|
|||
/// # assert!(config.is_ok());
|
||||
/// ```
|
||||
pub fn new(environment: Environment) -> ConfigBuilder {
|
||||
let config = Config::new(environment)
|
||||
.expect("ConfigBuilder::new(): couldn't get current directory.");
|
||||
|
||||
let root_dir = PathBuf::from(config.root());
|
||||
let config = Config::new(environment);
|
||||
ConfigBuilder {
|
||||
environment: config.environment,
|
||||
address: config.address,
|
||||
|
@ -70,7 +62,7 @@ impl ConfigBuilder {
|
|||
tls: None,
|
||||
limits: config.limits,
|
||||
extras: config.extras,
|
||||
root: root_dir,
|
||||
root: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,10 +255,10 @@ impl ConfigBuilder {
|
|||
/// .root("/my_app/dir")
|
||||
/// .unwrap();
|
||||
///
|
||||
/// assert_eq!(config.root(), Path::new("/my_app/dir"));
|
||||
/// assert_eq!(config.root().unwrap(), Path::new("/my_app/dir"));
|
||||
/// ```
|
||||
pub fn root<P: AsRef<Path>>(mut self, path: P) -> Self {
|
||||
self.root = path.as_ref().to_path_buf();
|
||||
self.root = Some(path.as_ref().to_path_buf());
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -298,9 +290,7 @@ impl ConfigBuilder {
|
|||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If the current working directory cannot be retrieved, returns a `BadCWD`
|
||||
/// error. If the address or secret key fail to parse, returns a `BadType`
|
||||
/// error.
|
||||
/// If the address or secret key fail to parse, returns a `BadType` error.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -323,16 +313,19 @@ impl ConfigBuilder {
|
|||
/// assert!(config.is_err());
|
||||
/// ```
|
||||
pub fn finalize(self) -> Result<Config> {
|
||||
let mut config = Config::new(self.environment)?;
|
||||
let mut config = Config::new(self.environment);
|
||||
config.set_address(self.address)?;
|
||||
config.set_port(self.port);
|
||||
config.set_workers(self.workers);
|
||||
config.set_keep_alive(self.keep_alive);
|
||||
config.set_log_level(self.log_level);
|
||||
config.set_extras(self.extras);
|
||||
config.set_root(self.root);
|
||||
config.set_limits(self.limits);
|
||||
|
||||
if let Some(root) = self.root {
|
||||
config.set_root(root);
|
||||
}
|
||||
|
||||
if let Some((certs_path, key_path)) = self.tls {
|
||||
config.set_tls(&certs_path, &key_path)?;
|
||||
}
|
||||
|
@ -348,8 +341,8 @@ impl ConfigBuilder {
|
|||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the current working directory cannot be retrieved or if the
|
||||
/// supplied address, secret key, or TLS configuration fail to parse.
|
||||
/// Panics if the supplied address, secret key, or TLS configuration fail to
|
||||
/// parse.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -371,9 +364,8 @@ impl ConfigBuilder {
|
|||
///
|
||||
/// # 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.
|
||||
/// Panics if the supplied address, secret key, or TLS configuration fail to
|
||||
/// parse. If a panic occurs, the error message `msg` is printed.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
|
|
@ -3,7 +3,6 @@ use std::net::ToSocketAddrs;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::convert::AsRef;
|
||||
use std::fmt;
|
||||
use std::env;
|
||||
|
||||
use super::custom_values::*;
|
||||
use {num_cpus, base64};
|
||||
|
@ -57,8 +56,10 @@ pub struct Config {
|
|||
pub limits: Limits,
|
||||
/// Extra parameters that aren't part of Rocket's core config.
|
||||
pub extras: HashMap<String, Value>,
|
||||
/// The path to the configuration file this config belongs to.
|
||||
pub config_path: PathBuf,
|
||||
/// The path to the configuration file this config was loaded from, if any.
|
||||
crate config_file_path: Option<PathBuf>,
|
||||
/// The path root-relative files will be rooted from.
|
||||
crate root_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
macro_rules! config_from_raw {
|
||||
|
@ -76,12 +77,7 @@ macro_rules! config_from_raw {
|
|||
|
||||
impl Config {
|
||||
/// Returns a builder for `Config` structure where the default parameters
|
||||
/// are set to those of `env`. The root configuration directory is set to
|
||||
/// the current working directory.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the current directory cannot be retrieved.
|
||||
/// are set to those of `env`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -99,25 +95,18 @@ impl Config {
|
|||
ConfigBuilder::new(env)
|
||||
}
|
||||
|
||||
/// Returns a `Config` with the parameters for the environment `env`. The
|
||||
/// root configuration directory is set to the current working directory.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If the current directory cannot be retrieved, a `BadCWD` error is
|
||||
/// returned.
|
||||
/// Returns a `Config` with the parameters for the environment `env`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use rocket::config::{Config, Environment};
|
||||
///
|
||||
/// let mut my_config = Config::new(Environment::Production).expect("cwd");
|
||||
/// let mut my_config = Config::new(Environment::Production);
|
||||
/// my_config.set_port(1001);
|
||||
/// ```
|
||||
pub fn new(env: Environment) -> Result<Config> {
|
||||
let cwd = env::current_dir().map_err(|_| ConfigError::BadCWD)?;
|
||||
Config::default(env, cwd.as_path().join("Rocket.custom.toml"))
|
||||
pub fn new(env: Environment) -> Config {
|
||||
Config::default(env)
|
||||
}
|
||||
|
||||
/// Returns a `Config` with the default parameters of the active environment
|
||||
|
@ -126,16 +115,14 @@ impl Config {
|
|||
/// If `ROCKET_ENV` is not set, the returned `Config` uses development
|
||||
/// environment parameters when the application was compiled in `debug` mode
|
||||
/// and production environment parameters when the application was compiled
|
||||
/// in `release` mode. The root configuration directory is set to the
|
||||
/// current working directory.
|
||||
/// in `release` mode.
|
||||
///
|
||||
/// This is equivalent to `Config::new(Environment::active()?)`.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If the current directory cannot be retrieved, a `BadCWD` error is
|
||||
/// returned. Returns a `BadEnv` error if `ROCKET_ENV` is set and contains
|
||||
/// an invalid or unknown environment name.
|
||||
/// Returns a `BadEnv` error if `ROCKET_ENV` is set and contains an invalid
|
||||
/// or unknown environment name.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -146,95 +133,94 @@ impl Config {
|
|||
/// my_config.set_port(1001);
|
||||
/// ```
|
||||
pub fn active() -> Result<Config> {
|
||||
Config::new(Environment::active()?)
|
||||
Ok(Config::new(Environment::active()?))
|
||||
}
|
||||
|
||||
/// Returns a `Config` with the default parameters of the development
|
||||
/// environment. The root configuration directory is set to the current
|
||||
/// working directory.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If the current directory cannot be retrieved, a `BadCWD` error is
|
||||
/// returned.
|
||||
/// environment.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use rocket::config::{Config, Environment};
|
||||
///
|
||||
/// let mut my_config = Config::development().unwrap();
|
||||
/// let mut my_config = Config::development();
|
||||
/// my_config.set_port(1001);
|
||||
/// ```
|
||||
pub fn development() -> Result<Config> {
|
||||
pub fn development() -> Config {
|
||||
Config::new(Environment::Development)
|
||||
}
|
||||
|
||||
/// Returns a `Config` with the default parameters of the staging
|
||||
/// environment. The root configuration directory is set to the current
|
||||
/// working directory.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If the current directory cannot be retrieved, a `BadCWD` error is
|
||||
/// returned.
|
||||
/// environment.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use rocket::config::{Config, Environment};
|
||||
///
|
||||
/// let mut my_config = Config::staging().expect("cwd");
|
||||
/// let mut my_config = Config::staging();
|
||||
/// my_config.set_port(1001);
|
||||
/// ```
|
||||
pub fn staging() -> Result<Config> {
|
||||
pub fn staging() -> Config {
|
||||
Config::new(Environment::Staging)
|
||||
}
|
||||
|
||||
/// Returns a `Config` with the default parameters of the production
|
||||
/// environment. The root configuration directory is set to the current
|
||||
/// working directory.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If the current directory cannot be retrieved, a `BadCWD` error is
|
||||
/// returned.
|
||||
/// environment.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use rocket::config::{Config, Environment};
|
||||
///
|
||||
/// let mut my_config = Config::production().expect("cwd");
|
||||
/// let mut my_config = Config::production();
|
||||
/// my_config.set_port(1001);
|
||||
/// ```
|
||||
pub fn production() -> Result<Config> {
|
||||
pub fn production() -> Config {
|
||||
Config::new(Environment::Production)
|
||||
}
|
||||
|
||||
/// Returns the default configuration for the environment `env` given that
|
||||
/// the configuration was stored at `config_path`. If `config_path` is not
|
||||
/// an absolute path, an `Err` of `ConfigError::BadFilePath` is returned.
|
||||
/// the configuration was stored at `config_file_path`.
|
||||
///
|
||||
/// # Error
|
||||
///
|
||||
/// Return a `BadFilePath` error if `path` does not have a parent.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if randomness cannot be retrieved from the OS.
|
||||
crate fn default<P>(env: Environment, path: P) -> Result<Config>
|
||||
crate fn default_from<P>(env: Environment, path: P) -> Result<Config>
|
||||
where P: AsRef<Path>
|
||||
{
|
||||
let config_path = path.as_ref().to_path_buf();
|
||||
if config_path.parent().is_none() {
|
||||
return Err(ConfigError::BadFilePath(config_path,
|
||||
"Configuration files must be rooted in a directory."));
|
||||
let mut config = Config::default(env);
|
||||
|
||||
let config_file_path = path.as_ref().to_path_buf();
|
||||
if let Some(parent) = config_file_path.parent() {
|
||||
config.set_root(parent);
|
||||
} else {
|
||||
let msg = "Configuration files must be rooted in a directory.";
|
||||
return Err(ConfigError::BadFilePath(config_file_path.clone(), msg));
|
||||
}
|
||||
|
||||
config.config_file_path = Some(config_file_path);
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
/// Returns the default configuration for the environment `env`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if randomness cannot be retrieved from the OS.
|
||||
crate fn default(env: Environment) -> Config {
|
||||
// Note: This may truncate if num_cpus::get() / 2 > u16::max. That's okay.
|
||||
let default_workers = (num_cpus::get() * 2) as u16;
|
||||
|
||||
// Use a generated secret key by default.
|
||||
let key = SecretKey::Generated(Key::generate());
|
||||
|
||||
Ok(match env {
|
||||
match env {
|
||||
Development => {
|
||||
Config {
|
||||
environment: Development,
|
||||
|
@ -247,7 +233,8 @@ impl Config {
|
|||
tls: None,
|
||||
limits: Limits::default(),
|
||||
extras: HashMap::new(),
|
||||
config_path,
|
||||
config_file_path: None,
|
||||
root_path: None,
|
||||
}
|
||||
}
|
||||
Staging => {
|
||||
|
@ -262,7 +249,8 @@ impl Config {
|
|||
tls: None,
|
||||
limits: Limits::default(),
|
||||
extras: HashMap::new(),
|
||||
config_path,
|
||||
config_file_path: None,
|
||||
root_path: None,
|
||||
}
|
||||
}
|
||||
Production => {
|
||||
|
@ -277,10 +265,11 @@ impl Config {
|
|||
tls: None,
|
||||
limits: Limits::default(),
|
||||
extras: HashMap::new(),
|
||||
config_path,
|
||||
config_file_path: None,
|
||||
root_path: None,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs a `BadType` error given the entry `name`, the invalid `val`
|
||||
|
@ -291,7 +280,7 @@ impl Config {
|
|||
actual: &'static str,
|
||||
expect: &'static str) -> ConfigError {
|
||||
let id = format!("{}.{}", self.environment, name);
|
||||
ConfigError::BadType(id, expect, actual, self.config_path.clone())
|
||||
ConfigError::BadType(id, expect, actual, self.config_file_path.clone())
|
||||
}
|
||||
|
||||
/// Sets the configuration `val` for the `name` entry. If the `name` is one
|
||||
|
@ -336,22 +325,16 @@ impl Config {
|
|||
/// # use std::path::Path;
|
||||
/// use rocket::config::{Config, Environment};
|
||||
///
|
||||
/// # use rocket::config::ConfigError;
|
||||
/// # fn config_test() -> Result<(), ConfigError> {
|
||||
/// let mut config = Config::new(Environment::Staging)?;
|
||||
/// config.set_root("/tmp/my_app");
|
||||
/// let mut config = Config::new(Environment::Staging);
|
||||
/// config.set_root("/var/my_app");
|
||||
///
|
||||
/// assert_eq!(config.root(), Path::new("/tmp/my_app"));
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// # #[cfg(not(windows))]
|
||||
/// assert_eq!(config.root().unwrap(), Path::new("/var/my_app"));
|
||||
/// # #[cfg(windows)]
|
||||
/// assert_eq!(config.root().unwrap(), Path::new("C:\\var\\my_app"));
|
||||
/// ```
|
||||
pub fn set_root<P: AsRef<Path>>(&mut self, path: P) {
|
||||
let new_path = match self.config_path.file_name() {
|
||||
Some(file) => path.as_ref().join(file),
|
||||
None => path.as_ref().join("Rocket.custom.toml")
|
||||
};
|
||||
|
||||
self.config_path = new_path
|
||||
self.root_path = Some(path.as_ref().into());
|
||||
}
|
||||
|
||||
/// Sets the address of `self` to `address`.
|
||||
|
@ -366,14 +349,10 @@ impl Config {
|
|||
/// ```rust
|
||||
/// use rocket::config::{Config, Environment};
|
||||
///
|
||||
/// # use rocket::config::ConfigError;
|
||||
/// # fn config_test() -> Result<(), ConfigError> {
|
||||
/// let mut config = Config::new(Environment::Staging)?;
|
||||
/// let mut config = Config::new(Environment::Staging);
|
||||
/// assert!(config.set_address("localhost").is_ok());
|
||||
/// assert!(config.set_address("::").is_ok());
|
||||
/// assert!(config.set_address("?").is_err());
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn set_address<A: Into<String>>(&mut self, address: A) -> Result<()> {
|
||||
let address = address.into();
|
||||
|
@ -392,12 +371,9 @@ impl Config {
|
|||
/// ```rust
|
||||
/// use rocket::config::{Config, Environment};
|
||||
///
|
||||
/// # use rocket::config::ConfigError;
|
||||
/// # fn config_test() -> Result<(), ConfigError> {
|
||||
/// let mut config = Config::new(Environment::Staging)?;
|
||||
/// let mut config = Config::new(Environment::Staging);
|
||||
/// config.set_port(1024);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// assert_eq!(config.port, 1024);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn set_port(&mut self, port: u16) {
|
||||
|
@ -411,12 +387,9 @@ impl Config {
|
|||
/// ```rust
|
||||
/// use rocket::config::{Config, Environment};
|
||||
///
|
||||
/// # use rocket::config::ConfigError;
|
||||
/// # fn config_test() -> Result<(), ConfigError> {
|
||||
/// let mut config = Config::new(Environment::Staging)?;
|
||||
/// let mut config = Config::new(Environment::Staging);
|
||||
/// config.set_workers(64);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// assert_eq!(config.workers, 64);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn set_workers(&mut self, workers: u16) {
|
||||
|
@ -431,17 +404,15 @@ impl Config {
|
|||
/// ```rust
|
||||
/// use rocket::config::Config;
|
||||
///
|
||||
/// # use rocket::config::ConfigError;
|
||||
/// # fn config_test() -> Result<(), ConfigError> {
|
||||
/// let mut config = Config::development()?;
|
||||
/// let mut config = Config::development();
|
||||
///
|
||||
/// // Set keep-alive timeout to 10 seconds.
|
||||
/// config.set_keep_alive(10);
|
||||
/// assert_eq!(config.keep_alive, Some(10));
|
||||
///
|
||||
/// // Disable keep-alive.
|
||||
/// config.set_keep_alive(0);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// assert_eq!(config.keep_alive, None);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn set_keep_alive(&mut self, timeout: u32) {
|
||||
|
@ -465,14 +436,10 @@ impl Config {
|
|||
/// ```rust
|
||||
/// use rocket::config::{Config, Environment};
|
||||
///
|
||||
/// # use rocket::config::ConfigError;
|
||||
/// # fn config_test() -> Result<(), ConfigError> {
|
||||
/// let mut config = Config::new(Environment::Staging)?;
|
||||
/// let mut config = Config::new(Environment::Staging);
|
||||
/// let key = "8Xui8SN4mI+7egV/9dlfYYLGQJeEx4+DwmSQLwDVXJg=";
|
||||
/// assert!(config.set_secret_key(key).is_ok());
|
||||
/// assert!(config.set_secret_key("hello? anyone there?").is_err());
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn set_secret_key<K: Into<String>>(&mut self, key: K) -> Result<()> {
|
||||
let key = key.into();
|
||||
|
@ -499,12 +466,9 @@ impl Config {
|
|||
/// ```rust
|
||||
/// use rocket::config::{Config, LoggingLevel, Environment};
|
||||
///
|
||||
/// # use rocket::config::ConfigError;
|
||||
/// # fn config_test() -> Result<(), ConfigError> {
|
||||
/// let mut config = Config::new(Environment::Staging)?;
|
||||
/// let mut config = Config::new(Environment::Staging);
|
||||
/// config.set_log_level(LoggingLevel::Critical);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// assert_eq!(config.log_level, LoggingLevel::Critical);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn set_log_level(&mut self, log_level: LoggingLevel) {
|
||||
|
@ -518,12 +482,8 @@ impl Config {
|
|||
/// ```rust
|
||||
/// use rocket::config::{Config, Limits};
|
||||
///
|
||||
/// # use rocket::config::ConfigError;
|
||||
/// # fn config_test() -> Result<(), ConfigError> {
|
||||
/// let mut config = Config::development()?;
|
||||
/// 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) {
|
||||
|
@ -550,7 +510,7 @@ impl Config {
|
|||
///
|
||||
/// # use rocket::config::ConfigError;
|
||||
/// # fn config_test() -> Result<(), ConfigError> {
|
||||
/// let mut config = Config::development()?;
|
||||
/// let mut config = Config::development();
|
||||
/// config.set_tls("/etc/ssl/my_certs.pem", "/etc/ssl/priv.key")?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
|
@ -605,9 +565,7 @@ impl Config {
|
|||
/// use std::collections::HashMap;
|
||||
/// use rocket::config::{Config, Environment};
|
||||
///
|
||||
/// # use rocket::config::ConfigError;
|
||||
/// # fn config_test() -> Result<(), ConfigError> {
|
||||
/// let mut config = Config::new(Environment::Staging)?;
|
||||
/// let mut config = Config::new(Environment::Staging);
|
||||
///
|
||||
/// // Create the `extras` map.
|
||||
/// let mut extras = HashMap::new();
|
||||
|
@ -615,8 +573,6 @@ impl Config {
|
|||
/// extras.insert("templates".to_string(), "my_dir".into());
|
||||
///
|
||||
/// config.set_extras(extras);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn set_extras(&mut self, extras: HashMap<String, Value>) {
|
||||
|
@ -632,9 +588,7 @@ impl Config {
|
|||
/// use std::collections::HashMap;
|
||||
/// use rocket::config::{Config, Environment};
|
||||
///
|
||||
/// # use rocket::config::ConfigError;
|
||||
/// # fn config_test() -> Result<(), ConfigError> {
|
||||
/// let mut config = Config::new(Environment::Staging)?;
|
||||
/// let mut config = Config::new(Environment::Staging);
|
||||
/// assert_eq!(config.extras().count(), 0);
|
||||
///
|
||||
/// // Add a couple of extras to the config.
|
||||
|
@ -644,8 +598,6 @@ impl Config {
|
|||
/// config.set_extras(extras);
|
||||
///
|
||||
/// assert_eq!(config.extras().count(), 2);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn extras<'a>(&'a self) -> impl Iterator<Item=(&'a str, &'a Value)> {
|
||||
|
@ -889,9 +841,13 @@ impl Config {
|
|||
.ok_or_else(|| self.bad_type(name, val.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.
|
||||
/// Returns the root path of the configuration, if one is known.
|
||||
///
|
||||
/// For configurations loaded from a `Rocket.toml` file, this will be the
|
||||
/// directory in which the file is stored. For instance, if the
|
||||
/// configuration file is at `/tmp/Rocket.toml`, the path `/tmp` is
|
||||
/// returned. For other configurations, this will be the path set via
|
||||
/// [`Config::set_root()`] or [`ConfigBuilder::root()`].
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -899,35 +855,47 @@ impl Config {
|
|||
/// use std::env::current_dir;
|
||||
/// use rocket::config::{Config, Environment};
|
||||
///
|
||||
/// let config = Config::new(Environment::Staging)
|
||||
/// .expect("can retrieve current directory");
|
||||
/// let mut config = Config::new(Environment::Staging);
|
||||
/// assert_eq!(config.root(), None);
|
||||
///
|
||||
/// assert_eq!(config.root(), current_dir().unwrap());
|
||||
/// let cwd = current_dir().expect("have cwd");
|
||||
/// config.set_root(&cwd);
|
||||
/// assert_eq!(config.root().unwrap(), cwd);
|
||||
/// ```
|
||||
pub fn root(&self) -> &Path {
|
||||
match self.config_path.parent() {
|
||||
Some(parent) => parent,
|
||||
None => panic!("root(): path {:?} has no parent", self.config_path)
|
||||
}
|
||||
pub fn root(&self) -> Option<&Path> {
|
||||
self.root_path.as_ref().map(|p| p.as_ref())
|
||||
}
|
||||
|
||||
/// If `path` is a relative path, `path` is appended to the
|
||||
/// [`Config::root()`] at which the configuration file for `self` is stored
|
||||
/// and the new path is returned. If `path` is absolute, `path` is returned
|
||||
/// unaltered.
|
||||
/// Returns `path` relative to this configuration.
|
||||
///
|
||||
/// The path that is returned depends on whether:
|
||||
///
|
||||
/// 1. Whether `path` is absolute or relative.
|
||||
/// 2. Whether there is a [`Config::root()`] configured.
|
||||
/// 3. Whether there is a current directory.
|
||||
///
|
||||
/// If `path` is absolute, it is returned unaltered. Otherwise, if `path` is
|
||||
/// relative and there is a root configured, the root is prepended to `path`
|
||||
/// and the newlt concatenated path is returned. Otherwise, if there is a
|
||||
/// current directory, it is preprended to `path` and the newly concatenated
|
||||
/// path is returned. Finally, if all else fails, the path is simply
|
||||
/// returned.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::env::current_dir;
|
||||
/// use std::path::Path;
|
||||
/// use std::env::current_dir;
|
||||
///
|
||||
/// use rocket::config::{Config, Environment};
|
||||
///
|
||||
/// let config = Config::new(Environment::Staging)
|
||||
/// .expect("can retrieve current directory");
|
||||
/// let mut config = Config::new(Environment::Staging);
|
||||
///
|
||||
/// assert_eq!(config.root(), current_dir().unwrap());
|
||||
/// assert_eq!(config.root_relative("abc"), config.root().join("abc"));
|
||||
/// let cwd = current_dir().expect("have cwd");
|
||||
/// config.set_root(&cwd);
|
||||
/// assert_eq!(config.root().unwrap(), cwd);
|
||||
///
|
||||
/// assert_eq!(config.root_relative("abc"), cwd.join("abc"));
|
||||
/// # #[cfg(not(windows))]
|
||||
/// assert_eq!(config.root_relative("/abc"), Path::new("/abc"));
|
||||
/// # #[cfg(windows)]
|
||||
|
@ -937,8 +905,12 @@ impl Config {
|
|||
let path = path.as_ref();
|
||||
if path.is_absolute() {
|
||||
path.into()
|
||||
} else if let Some(root) = self.root() {
|
||||
root.join(path)
|
||||
} else if let Ok(cwd) = ::std::env::current_dir() {
|
||||
cwd.join(path)
|
||||
} else {
|
||||
self.root().join(path)
|
||||
path.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,12 @@ pub enum Environment {
|
|||
}
|
||||
|
||||
impl Environment {
|
||||
/// List of all of the possible environments.
|
||||
crate const ALL: [Environment; 3] = [Development, Staging, Production];
|
||||
|
||||
/// String of all valid environments.
|
||||
crate const VALID: &'static str = "development, staging, production";
|
||||
|
||||
/// Retrieves the "active" environment as determined by the `ROCKET_ENV`
|
||||
/// environment variable. If `ROCKET_ENV` is not set, returns `Development`
|
||||
/// when the application was compiled in `debug` mode and `Production` when
|
||||
|
@ -39,17 +45,6 @@ impl Environment {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a string with a comma-separated list of valid environments.
|
||||
crate fn valid() -> &'static str {
|
||||
"development, staging, production"
|
||||
}
|
||||
|
||||
/// Returns a list of all of the possible environments.
|
||||
#[inline]
|
||||
crate fn all() -> [Environment; 3] {
|
||||
[Development, Staging, Production]
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` is `Environment::Development`.
|
||||
///
|
||||
/// # Example
|
||||
|
|
|
@ -10,8 +10,6 @@ use yansi::Color::White;
|
|||
/// The type of a configuration error.
|
||||
#[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.
|
||||
|
@ -35,7 +33,7 @@ pub enum ConfigError {
|
|||
/// A config key was specified with a value of the wrong type.
|
||||
///
|
||||
/// Parameters: (entry_name, expected_type, actual_type, filename)
|
||||
BadType(String, &'static str, &'static str, PathBuf),
|
||||
BadType(String, &'static str, &'static str, Option<PathBuf>),
|
||||
/// There was a TOML parsing error.
|
||||
///
|
||||
/// Parameters: (toml_source_string, filename, error_description, line/col)
|
||||
|
@ -57,9 +55,8 @@ pub enum ConfigError {
|
|||
impl ConfigError {
|
||||
/// Prints this configuration error with Rocket formatting.
|
||||
pub fn pretty_print(&self) {
|
||||
let valid_envs = Environment::valid();
|
||||
let valid_envs = Environment::VALID;
|
||||
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"),
|
||||
Io(ref error, param) => {
|
||||
|
@ -82,7 +79,10 @@ impl ConfigError {
|
|||
}
|
||||
BadType(ref name, expected, actual, ref filename) => {
|
||||
error!("{} key could not be parsed", White.paint(name));
|
||||
info_!("in {:?}", White.paint(filename));
|
||||
if let Some(filename) = filename {
|
||||
info_!("in {:?}", White.paint(filename));
|
||||
}
|
||||
|
||||
info_!("expected value to be {}, but found {}",
|
||||
White.paint(expected), White.paint(actual));
|
||||
}
|
||||
|
@ -133,7 +133,6 @@ impl ConfigError {
|
|||
impl fmt::Display for ConfigError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
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"),
|
||||
Io(ref e, p) => write!(f, "I/O error while setting '{}': {}", p, e),
|
||||
|
@ -158,7 +157,6 @@ impl fmt::Display for ConfigError {
|
|||
impl Error for ConfigError {
|
||||
fn description(&self) -> &str {
|
||||
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",
|
||||
Io(..) => "an I/O error occured while setting a configuration parameter",
|
||||
|
@ -177,7 +175,6 @@ 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,
|
||||
|
@ -193,7 +190,7 @@ impl PartialEq for ConfigError {
|
|||
k1 == k2 && v1 == v2
|
||||
}
|
||||
(&Missing(ref k1), &Missing(ref k2)) => k1 == k2,
|
||||
(&BadCWD, _) | (&NotFound, _) | (&IoError, _) | (&Io(..), _)
|
||||
(&NotFound, _) | (&IoError, _) | (&Io(..), _)
|
||||
| (&BadFilePath(..), _) | (&BadEnv(..), _) | (&ParseError(..), _)
|
||||
| (&UnknownKey(..), _) | (&BadEntry(..), _) | (&BadType(..), _)
|
||||
| (&BadEnvVal(..), _) | (&Missing(..), _) => false
|
||||
|
|
|
@ -229,29 +229,6 @@ pub struct RocketConfig {
|
|||
}
|
||||
|
||||
impl RocketConfig {
|
||||
/// Create a new configuration using the passed in `config` for all
|
||||
/// environments. The Rocket.toml file is ignored, as are environment
|
||||
/// variables.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// If the current working directory can't be retrieved, this function
|
||||
/// panics.
|
||||
pub fn new(config: Config) -> RocketConfig {
|
||||
let f = config.config_path.clone();
|
||||
let active_env = config.environment;
|
||||
|
||||
// None of these unwraps should fail since the filename is coming from
|
||||
// an existing config.
|
||||
let mut configs = HashMap::new();
|
||||
configs.insert(Development, Config::default(Development, &f).unwrap());
|
||||
configs.insert(Staging, Config::default(Staging, &f).unwrap());
|
||||
configs.insert(Production, Config::default(Production, &f).unwrap());
|
||||
configs.insert(active_env, config);
|
||||
|
||||
RocketConfig { active_env, config: configs }
|
||||
}
|
||||
|
||||
/// Read the configuration from the `Rocket.toml` file. The file is search
|
||||
/// for recursively up the tree, starting from the CWD.
|
||||
pub fn read() -> Result<RocketConfig> {
|
||||
|
@ -271,11 +248,17 @@ impl RocketConfig {
|
|||
|
||||
/// Return the default configuration for all environments and marks the
|
||||
/// active environment (via the CONFIG_ENV variable) as active.
|
||||
pub fn active_default<P: AsRef<Path>>(filename: P) -> Result<RocketConfig> {
|
||||
pub fn active_default_from(filename: Option<&Path>) -> Result<RocketConfig> {
|
||||
let mut defaults = HashMap::new();
|
||||
defaults.insert(Development, Config::default(Development, &filename)?);
|
||||
defaults.insert(Staging, Config::default(Staging, &filename)?);
|
||||
defaults.insert(Production, Config::default(Production, &filename)?);
|
||||
if let Some(path) = filename {
|
||||
defaults.insert(Development, Config::default_from(Development, &path)?);
|
||||
defaults.insert(Staging, Config::default_from(Staging, &path)?);
|
||||
defaults.insert(Production, Config::default_from(Production, &path)?);
|
||||
} else {
|
||||
defaults.insert(Development, Config::default(Development));
|
||||
defaults.insert(Staging, Config::default(Staging));
|
||||
defaults.insert(Production, Config::default(Production));
|
||||
}
|
||||
|
||||
let mut config = RocketConfig {
|
||||
active_env: Environment::active()?,
|
||||
|
@ -287,12 +270,18 @@ impl RocketConfig {
|
|||
Ok(config)
|
||||
}
|
||||
|
||||
/// Return the default configuration for all environments and marks the
|
||||
/// active environment (via the CONFIG_ENV variable) as active.
|
||||
pub fn active_default() -> Result<RocketConfig> {
|
||||
RocketConfig::active_default_from(None)
|
||||
}
|
||||
|
||||
/// Iteratively search for `CONFIG_FILENAME` starting at the current working
|
||||
/// directory and working up through its parents. Returns the path to the
|
||||
/// file or an Error::NoKey if the file couldn't be found. If the current
|
||||
/// working directory can't be determined, return `BadCWD`.
|
||||
fn find() -> Result<PathBuf> {
|
||||
let cwd = env::current_dir().map_err(|_| ConfigError::BadCWD)?;
|
||||
let cwd = env::current_dir().map_err(|_| ConfigError::NotFound)?;
|
||||
let mut current = cwd.as_path();
|
||||
|
||||
loop {
|
||||
|
@ -365,7 +354,7 @@ impl RocketConfig {
|
|||
Err(e) => return Err(ConfigError::BadEnvVal(key, val, e))
|
||||
};
|
||||
|
||||
for env in &Environment::all() {
|
||||
for env in &Environment::ALL {
|
||||
match self.get_mut(*env).set_raw(&key, &toml_val) {
|
||||
Err(ConfigError::BadType(_, exp, actual, _)) => {
|
||||
let e = format!("expected {}, but found {}", exp, actual);
|
||||
|
@ -397,7 +386,7 @@ impl RocketConfig {
|
|||
};
|
||||
|
||||
// Create a config with the defaults; set the env to the active one.
|
||||
let mut config = RocketConfig::active_default(filename)?;
|
||||
let mut config = RocketConfig::active_default_from(Some(filename.as_ref()))?;
|
||||
|
||||
// Store all of the global overrides, if any, for later use.
|
||||
let mut global = None;
|
||||
|
@ -408,7 +397,7 @@ impl RocketConfig {
|
|||
let kv_pairs = match value.as_table() {
|
||||
Some(table) => table,
|
||||
None => return Err(ConfigError::BadType(
|
||||
entry, "a table", value.type_str(), path.clone()
|
||||
entry, "a table", value.type_str(), Some(path.clone())
|
||||
))
|
||||
};
|
||||
|
||||
|
@ -428,7 +417,7 @@ impl RocketConfig {
|
|||
|
||||
// Override all of the environments with the global values.
|
||||
if let Some(ref global_kv_pairs) = global {
|
||||
for env in &Environment::all() {
|
||||
for env in &Environment::ALL {
|
||||
config.set_from_table(*env, global_kv_pairs)?;
|
||||
}
|
||||
}
|
||||
|
@ -467,16 +456,11 @@ crate fn init() -> Config {
|
|||
| ParseError(..) | BadEntry(..) | BadEnv(..) | BadType(..) | Io(..)
|
||||
| BadFilePath(..) | BadEnvVal(..) | UnknownKey(..)
|
||||
| Missing(..) => bail(e),
|
||||
IoError | BadCWD => warn!("Failed reading Rocket.toml. Using defaults."),
|
||||
IoError => warn!("Failed reading Rocket.toml. Using defaults."),
|
||||
NotFound => { /* try using the default below */ }
|
||||
}
|
||||
|
||||
let default_path = match env::current_dir() {
|
||||
Ok(path) => path.join(&format!(".{}.{}", "default", CONFIG_FILENAME)),
|
||||
Err(_) => bail(ConfigError::BadCWD)
|
||||
};
|
||||
|
||||
RocketConfig::active_default(&default_path).unwrap_or_else(|e| bail(e))
|
||||
RocketConfig::active_default().unwrap_or_else(|e| bail(e))
|
||||
});
|
||||
|
||||
// FIXME: Should probably store all of the config.
|
||||
|
@ -522,7 +506,7 @@ mod test {
|
|||
}
|
||||
|
||||
fn active_default() -> Result<RocketConfig> {
|
||||
RocketConfig::active_default(TEST_CONFIG_FILENAME)
|
||||
RocketConfig::active_default()
|
||||
}
|
||||
|
||||
fn default_config(env: Environment) -> ConfigBuilder {
|
||||
|
@ -1073,7 +1057,7 @@ mod test {
|
|||
let _env_lock = ENV_LOCK.lock().unwrap();
|
||||
|
||||
// Test first that we can override each environment.
|
||||
for env in &Environment::all() {
|
||||
for env in &Environment::ALL {
|
||||
env::set_var(CONFIG_ENV, env.to_string());
|
||||
|
||||
check_config!(RocketConfig::parse(format!(r#"
|
||||
|
@ -1127,14 +1111,14 @@ mod test {
|
|||
|
||||
let rconfig = active_default().unwrap();
|
||||
// Check that it overrides the active config.
|
||||
for env in &Environment::all() {
|
||||
for env in &Environment::ALL {
|
||||
env::set_var(CONFIG_ENV, env.to_string());
|
||||
let rconfig = active_default().unwrap();
|
||||
check_value(&*key.to_lowercase(), val, rconfig.active());
|
||||
}
|
||||
|
||||
// And non-active configs.
|
||||
for env in &Environment::all() {
|
||||
for env in &Environment::ALL {
|
||||
check_value(&*key.to_lowercase(), val, rconfig.get(*env));
|
||||
}
|
||||
}
|
||||
|
@ -1172,7 +1156,7 @@ mod test {
|
|||
check_value(&*key.to_lowercase(), val, r.active());
|
||||
|
||||
// And non-active configs.
|
||||
for env in &Environment::all() {
|
||||
for env in &Environment::ALL {
|
||||
check_value(&*key.to_lowercase(), val, r.get(*env));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -697,7 +697,7 @@ impl<'r> Request<'r> {
|
|||
impl<'r> Request<'r> {
|
||||
// Only used by doc-tests! Needs to be `pub` because doc-test are external.
|
||||
pub fn example<F: Fn(&mut Request)>(method: Method, uri: &str, f: F) {
|
||||
let rocket = Rocket::custom(Config::development().unwrap());
|
||||
let rocket = Rocket::custom(Config::development());
|
||||
let uri = Origin::parse(uri).expect("invalid URI in example");
|
||||
let mut request = Request::new(&rocket, method, uri);
|
||||
f(&mut request);
|
||||
|
|
|
@ -20,7 +20,7 @@ macro_rules! assert_headers {
|
|||
$(expected.entry($key).or_insert(vec![]).append(&mut vec![$($value),+]);)+
|
||||
|
||||
// Dispatch the request and check that the headers are what we expect.
|
||||
let config = Config::development().unwrap();
|
||||
let config = Config::development();
|
||||
let r = Rocket::custom(config);
|
||||
let req = Request::from_hyp(&r, h_method, h_headers, h_uri, h_addr).unwrap();
|
||||
let actual_headers = req.headers();
|
||||
|
|
|
@ -401,7 +401,7 @@ mod tests {
|
|||
fn req_route_mt_collide<S1, S2>(m: Method, mt1: S1, mt2: S2) -> bool
|
||||
where S1: Into<Option<&'static str>>, S2: Into<Option<&'static str>>
|
||||
{
|
||||
let rocket = Rocket::custom(Config::development().unwrap());
|
||||
let rocket = Rocket::custom(Config::development());
|
||||
let mut req = Request::new(&rocket, m, Origin::dummy());
|
||||
if let Some(mt_str) = mt1.into() {
|
||||
if m.supports_payload() {
|
||||
|
@ -468,7 +468,7 @@ mod tests {
|
|||
}
|
||||
|
||||
fn req_route_path_match(a: &'static str, b: &'static str) -> bool {
|
||||
let rocket = Rocket::custom(Config::development().unwrap());
|
||||
let rocket = Rocket::custom(Config::development());
|
||||
let req = Request::new(&rocket, Get, Origin::parse(a).expect("valid URI"));
|
||||
let route = Route::ranked(0, Get, b.to_string(), dummy_handler);
|
||||
route.matches(&req)
|
||||
|
|
|
@ -228,7 +228,7 @@ mod test {
|
|||
}
|
||||
|
||||
fn route<'a>(router: &'a Router, method: Method, uri: &str) -> Option<&'a Route> {
|
||||
let rocket = Rocket::custom(Config::development().unwrap());
|
||||
let rocket = Rocket::custom(Config::development());
|
||||
let request = Request::new(&rocket, method, Origin::parse(uri).unwrap());
|
||||
let matches = router.route(&request);
|
||||
if matches.len() > 0 {
|
||||
|
@ -239,7 +239,7 @@ mod test {
|
|||
}
|
||||
|
||||
fn matches<'a>(router: &'a Router, method: Method, uri: &str) -> Vec<&'a Route> {
|
||||
let rocket = Rocket::custom(Config::development().unwrap());
|
||||
let rocket = Rocket::custom(Config::development());
|
||||
let request = Request::new(&rocket, method, Origin::parse(uri).unwrap());
|
||||
router.route(&request)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue