mirror of https://github.com/rwf2/Rocket.git
Document Config. Cleaner lib/handler docs.
This commit is contained in:
parent
123c684f62
commit
8d8d504b59
|
@ -22,7 +22,7 @@ pub struct Config {
|
||||||
pub env: Environment,
|
pub env: Environment,
|
||||||
session_key: RwLock<Option<String>>,
|
session_key: RwLock<Option<String>>,
|
||||||
extras: HashMap<String, Value>,
|
extras: HashMap<String, Value>,
|
||||||
filename: String,
|
filepath: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! parse {
|
macro_rules! parse {
|
||||||
|
@ -34,10 +34,13 @@ macro_rules! parse {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn default_for(env: Environment, filename: &str) -> config::Result<Config> {
|
/// Returns the default configuration for the environment `env` given that
|
||||||
let file_path = Path::new(filename);
|
/// the configuration was stored at `filepath`. If `filepath` is not an
|
||||||
|
/// absolute path, an `Err` of `ConfigError::BadFilePath` is returned.
|
||||||
|
pub fn default_for(env: Environment, filepath: &str) -> config::Result<Config> {
|
||||||
|
let file_path = Path::new(filepath);
|
||||||
if file_path.parent().is_none() {
|
if file_path.parent().is_none() {
|
||||||
return Err(ConfigError::BadFilePath(filename.to_string(),
|
return Err(ConfigError::BadFilePath(filepath.to_string(),
|
||||||
"Configuration files must be rooted in a directory."));
|
"Configuration files must be rooted in a directory."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +53,7 @@ impl Config {
|
||||||
session_key: RwLock::new(None),
|
session_key: RwLock::new(None),
|
||||||
extras: HashMap::new(),
|
extras: HashMap::new(),
|
||||||
env: env,
|
env: env,
|
||||||
filename: filename.to_string(),
|
filepath: filepath.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Staging => {
|
Staging => {
|
||||||
|
@ -61,7 +64,7 @@ impl Config {
|
||||||
session_key: RwLock::new(None),
|
session_key: RwLock::new(None),
|
||||||
extras: HashMap::new(),
|
extras: HashMap::new(),
|
||||||
env: env,
|
env: env,
|
||||||
filename: filename.to_string(),
|
filepath: filepath.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Production => {
|
Production => {
|
||||||
|
@ -72,18 +75,34 @@ impl Config {
|
||||||
session_key: RwLock::new(None),
|
session_key: RwLock::new(None),
|
||||||
extras: HashMap::new(),
|
extras: HashMap::new(),
|
||||||
env: env,
|
env: env,
|
||||||
filename: filename.to_string(),
|
filepath: filepath.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs a `BadType` error given the entry `name`, the invalid `val`
|
||||||
|
/// at that entry, and the `expect`ed type name.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn bad_type(&self, name: &str, val: &Value, expect: &'static str) -> ConfigError {
|
fn bad_type(&self, name: &str, val: &Value, expect: &'static str) -> ConfigError {
|
||||||
let id = format!("{}.{}", self.env, name);
|
let id = format!("{}.{}", self.env, name);
|
||||||
ConfigError::BadType(id, expect, val.type_str(), self.filename.clone())
|
ConfigError::BadType(id, expect, val.type_str(), self.filepath.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the configuration `val` for the `name` entry. If the `name` is one
|
||||||
|
/// of "address", "port", "session_key", or "log" (the "default" values),
|
||||||
|
/// the appropriate value in the `self` Config structure is set. Otherwise,
|
||||||
|
/// the value is stored as an `extra`.
|
||||||
|
///
|
||||||
|
/// For each of the default values, the following `Value` variant is
|
||||||
|
/// expected. If a different variant is supplied, a `BadType` `Err` is
|
||||||
|
/// returned:
|
||||||
|
///
|
||||||
|
/// * **address**: String
|
||||||
|
/// * **port**: Integer
|
||||||
|
/// * **session_key**: String (192-bit base64)
|
||||||
|
/// * **log**: String
|
||||||
|
///
|
||||||
pub fn set(&mut self, name: &str, val: &Value) -> config::Result<()> {
|
pub fn set(&mut self, name: &str, val: &Value) -> config::Result<()> {
|
||||||
if name == "address" {
|
if name == "address" {
|
||||||
let address_str = parse!(self, name, val, as_str, "a string")?;
|
let address_str = parse!(self, name, val, as_str, "a string")?;
|
||||||
|
@ -122,76 +141,124 @@ impl Config {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Moves the session key string out of the `self` Config, if there is one.
|
||||||
|
/// Because the value is moved out, subsequent calls will result in a return
|
||||||
|
/// value of `None`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::config::{Config, Environment, Value};
|
||||||
|
///
|
||||||
|
/// // Create a new config with a session key.
|
||||||
|
/// let key = "adL5fFIPmZBrlyHk2YT4NLV3YCk2gFXz".to_string();
|
||||||
|
/// let config = Config::default_for(Environment::Staging, "/custom").unwrap()
|
||||||
|
/// .session_key(key.clone());
|
||||||
|
///
|
||||||
|
/// // Get the key for the first time.
|
||||||
|
/// let session_key = config.take_session_key();
|
||||||
|
/// assert_eq!(session_key, Some(key.clone()));
|
||||||
|
///
|
||||||
|
/// // Try to get the key again.
|
||||||
|
/// let session_key_again = config.take_session_key();
|
||||||
|
/// assert_eq!(session_key_again, None);
|
||||||
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn take_session_key(&self) -> Option<String> {
|
pub fn take_session_key(&self) -> Option<String> {
|
||||||
let mut key = self.session_key.write().expect("couldn't lock session key");
|
let mut key = self.session_key.write().expect("couldn't lock session key");
|
||||||
key.take()
|
key.take()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over the names and values of all of the extras in
|
||||||
|
/// the `self` Config.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn extras<'a>(&'a self) -> impl Iterator<Item=(&'a String, &'a Value)> {
|
pub fn extras<'a>(&'a self) -> impl Iterator<Item=(&'a str, &'a Value)> {
|
||||||
self.extras.iter()
|
self.extras.iter().map(|(k, v)| (k.as_str(), v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to retrieve the extra named `name` as a string. If an extra
|
||||||
|
/// with that name doesn't exist, returns an `Err` of `NotFound`. If an
|
||||||
|
/// extra with that name does exist but is not a string, returns a `BadType`
|
||||||
|
/// error.
|
||||||
pub fn get_str<'a>(&'a self, name: &str) -> config::Result<&'a str> {
|
pub fn get_str<'a>(&'a self, name: &str) -> config::Result<&'a str> {
|
||||||
let value = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
|
let value = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
|
||||||
parse!(self, name, value, as_str, "a string")
|
parse!(self, name, value, as_str, "a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to retrieve the extra named `name` as an integer. If an extra
|
||||||
|
/// with that name doesn't exist, returns an `Err` of `NotFound`. If an
|
||||||
|
/// extra with that name does exist but is not an integer, returns a
|
||||||
|
/// `BadType` error.
|
||||||
pub fn get_int(&self, name: &str) -> config::Result<i64> {
|
pub fn get_int(&self, name: &str) -> config::Result<i64> {
|
||||||
let value = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
|
let value = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
|
||||||
parse!(self, name, value, as_integer, "an integer")
|
parse!(self, name, value, as_integer, "an integer")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to retrieve the extra named `name` as a boolean. If an extra
|
||||||
|
/// with that name doesn't exist, returns an `Err` of `NotFound`. If an
|
||||||
|
/// extra with that name does exist but is not a boolean, returns a
|
||||||
|
/// `BadType` error.
|
||||||
pub fn get_bool(&self, name: &str) -> config::Result<bool> {
|
pub fn get_bool(&self, name: &str) -> config::Result<bool> {
|
||||||
let value = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
|
let value = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
|
||||||
parse!(self, name, value, as_bool, "a boolean")
|
parse!(self, name, value, as_bool, "a boolean")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to retrieve the extra named `name` as a float. If an extra
|
||||||
|
/// with that name doesn't exist, returns an `Err` of `NotFound`. If an
|
||||||
|
/// extra with that name does exist but is not a float, returns a
|
||||||
|
/// `BadType` error.
|
||||||
pub fn get_float(&self, name: &str) -> config::Result<f64> {
|
pub fn get_float(&self, name: &str) -> config::Result<f64> {
|
||||||
let value = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
|
let value = self.extras.get(name).ok_or_else(|| ConfigError::NotFound)?;
|
||||||
parse!(self, name, value, as_float, "a float")
|
parse!(self, name, value, as_float, "a float")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
pub fn root(&self) -> &Path {
|
pub fn root(&self) -> &Path {
|
||||||
match Path::new(self.filename.as_str()).parent() {
|
match Path::new(self.filepath.as_str()).parent() {
|
||||||
Some(parent) => parent,
|
Some(parent) => parent,
|
||||||
None => panic!("root(): filename {} has no parent", self.filename)
|
None => panic!("root(): filepath {} has no parent", self.filepath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Builder pattern below, mostly for testing.
|
/// Sets the `address` in `self` to `var` and returns the structure.
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn address(mut self, var: String) -> Self {
|
pub fn address(mut self, var: String) -> Self {
|
||||||
self.address = var;
|
self.address = var;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the `port` in `self` to `var` and returns the structure.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn port(mut self, var: usize) -> Self {
|
pub fn port(mut self, var: usize) -> Self {
|
||||||
self.port = var;
|
self.port = var;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the `log_level` in `self` to `var` and returns the structure.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn log_level(mut self, var: LoggingLevel) -> Self {
|
pub fn log_level(mut self, var: LoggingLevel) -> Self {
|
||||||
self.log_level = var;
|
self.log_level = var;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the `session_key` in `self` to `var` and returns the structure.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn session_key(mut self, var: String) -> Self {
|
pub fn session_key(mut self, var: String) -> Self {
|
||||||
self.session_key = RwLock::new(Some(var));
|
self.session_key = RwLock::new(Some(var));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the `env` in `self` to `var` and returns the structure.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn env(mut self, var: Environment) -> Self {
|
pub fn env(mut self, var: Environment) -> Self {
|
||||||
self.env = var;
|
self.env = var;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds an extra configuration parameter with `name` and `value` to `self`
|
||||||
|
/// and returns the structure.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn extra(mut self, name: &str, value: &Value) -> Self {
|
pub fn extra(mut self, name: &str, value: &Value) -> Self {
|
||||||
self.extras.insert(name.into(), value.clone());
|
self.extras.insert(name.into(), value.clone());
|
||||||
|
@ -214,7 +281,7 @@ impl PartialEq for Config {
|
||||||
&& self.log_level == other.log_level
|
&& self.log_level == other.log_level
|
||||||
&& self.env == other.env
|
&& self.env == other.env
|
||||||
&& self.extras == other.extras
|
&& self.extras == other.extras
|
||||||
&& self.filename == other.filename
|
&& self.filepath == other.filepath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,9 @@ pub use self::environment::Environment;
|
||||||
pub use self::config::Config;
|
pub use self::config::Config;
|
||||||
use self::Environment::*;
|
use self::Environment::*;
|
||||||
|
|
||||||
use toml::{self, Table};
|
use toml;
|
||||||
|
pub use toml::{Array, Table, Value};
|
||||||
|
|
||||||
use logger::{self, LoggingLevel};
|
use logger::{self, LoggingLevel};
|
||||||
|
|
||||||
static INIT: Once = ONCE_INIT;
|
static INIT: Once = ONCE_INIT;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! The types of request and error handlers and their return values.
|
||||||
|
|
||||||
use data::Data;
|
use data::Data;
|
||||||
use request::Request;
|
use request::Request;
|
||||||
use response::{self, Response, Responder};
|
use response::{self, Response, Responder};
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//! as well as a [full, detailed guide](https://rocket.rs/guide). If you'd like
|
//! as well as a [full, detailed guide](https://rocket.rs/guide). If you'd like
|
||||||
//! pointers on getting started, see the
|
//! pointers on getting started, see the
|
||||||
//! [quickstart](https://rocket.rs/guide/quickstart) or [getting
|
//! [quickstart](https://rocket.rs/guide/quickstart) or [getting
|
||||||
//! started](https://rocket.rs/guide/getting_started) chapters of the guide.
|
//! started](https://rocket.rs/guide/getting-started) chapters of the guide.
|
||||||
//!
|
//!
|
||||||
//! You may also be interested in looking at the [contrib API
|
//! You may also be interested in looking at the [contrib API
|
||||||
//! documentation](../rocket_contrib), which contains JSON and templating
|
//! documentation](../rocket_contrib), which contains JSON and templating
|
||||||
|
@ -42,10 +42,10 @@
|
||||||
//! rocket_codegen = "*"
|
//! rocket_codegen = "*"
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! If you'll be deploying your project to Crates.io, you'll need to change the
|
//! If you'll be deploying your project to [crates.io](https://crates.io),
|
||||||
//! "*" to the current version of Rocket.
|
//! you'll need to change the "*" to the current version of Rocket.
|
||||||
//!
|
//!
|
||||||
//! Then, add the following to top of your `main.rs` file:
|
//! Then, add the following to the top of your `main.rs` file:
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! #![feature(plugin)]
|
//! #![feature(plugin)]
|
||||||
|
@ -79,14 +79,14 @@
|
||||||
//!
|
//!
|
||||||
//! Rocket and Rocket libraries are configured via the `Rocket.toml` file. For
|
//! Rocket and Rocket libraries are configured via the `Rocket.toml` file. For
|
||||||
//! more information on how to configure Rocket, see the [configuration
|
//! more information on how to configure Rocket, see the [configuration
|
||||||
//! section](/guide/configuration) of the guide as well as the [config](config)
|
//! section](https://rocket.rs/guide/getting-started/#configuration) of the
|
||||||
//! module documentation.
|
//! guide as well as the [config](config) module documentation.
|
||||||
//!
|
//!
|
||||||
//! ## Testing
|
//! ## Testing
|
||||||
//!
|
//!
|
||||||
//! Rocket includes a small testing library that can be used to test your Rocket
|
//! Rocket includes a small testing library that can be used to test your Rocket
|
||||||
//! application. The library's API is unstable. For information on how to test
|
//! application. For information on how to test your Rocket applications, the
|
||||||
//! your Rocket applications, the [testing module](testing) documentation.
|
//! [testing module](testing) documentation.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
|
|
|
@ -155,6 +155,7 @@ impl Rocket {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
#[inline(always)]
|
||||||
pub fn dispatch<'r>(&self, request: &'r mut Request, data: Data) -> Response<'r> {
|
pub fn dispatch<'r>(&self, request: &'r mut Request, data: Data) -> Response<'r> {
|
||||||
// Do a bit of preprocessing before routing.
|
// Do a bit of preprocessing before routing.
|
||||||
self.preprocess_request(request, &data);
|
self.preprocess_request(request, &data);
|
||||||
|
@ -173,7 +174,9 @@ impl Rocket {
|
||||||
// Rust thinks `request` is still borrowed here, but it's
|
// Rust thinks `request` is still borrowed here, but it's
|
||||||
// obviously not (data has nothing to do with it), so we
|
// obviously not (data has nothing to do with it), so we
|
||||||
// convince it to give us another mutable reference.
|
// convince it to give us another mutable reference.
|
||||||
// FIXME: Pay the cost to copy Request into UnsafeCell?
|
// FIXME: Pay the cost to copy Request into UnsafeCell? Pay the
|
||||||
|
// cost to use RefCell? Move the call to `issue_response` here
|
||||||
|
// to move Request and move directly into a RefCell?
|
||||||
let request: &'r mut Request = unsafe {
|
let request: &'r mut Request = unsafe {
|
||||||
&mut *(request as *const Request as *mut Request)
|
&mut *(request as *const Request as *mut Request)
|
||||||
};
|
};
|
||||||
|
@ -198,7 +201,7 @@ impl Rocket {
|
||||||
/// returns a failure, or there are no matching handlers willing to accept
|
/// returns a failure, or there are no matching handlers willing to accept
|
||||||
/// the request, this function returns an `Err` with the status code.
|
/// the request, this function returns an `Err` with the status code.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[inline]
|
#[inline(always)]
|
||||||
pub fn route<'r>(&self, request: &'r Request, mut data: Data)
|
pub fn route<'r>(&self, request: &'r Request, mut data: Data)
|
||||||
-> handler::Outcome<'r> {
|
-> handler::Outcome<'r> {
|
||||||
// Go through the list of matching routes until we fail or succeed.
|
// Go through the list of matching routes until we fail or succeed.
|
||||||
|
|
|
@ -42,6 +42,7 @@ impl Router {
|
||||||
.filter(|r| r.collides_with(req))
|
.filter(|r| r.collides_with(req))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
// FIXME: Presort vector to avoid a sort on each route.
|
||||||
matches.sort_by(|a, b| a.rank.cmp(&b.rank));
|
matches.sort_by(|a, b| a.rank.cmp(&b.rank));
|
||||||
trace_!("All matches: {:?}", matches);
|
trace_!("All matches: {:?}", matches);
|
||||||
matches
|
matches
|
||||||
|
|
Loading…
Reference in New Issue