Modularize contrib.

This commit is contained in:
Sergio Benitez 2018-10-06 17:24:11 -07:00
parent 28f2a33abd
commit 9cb031a47d
31 changed files with 285 additions and 331 deletions

View File

@ -11,46 +11,46 @@ keywords = ["rocket", "web", "framework", "contrib", "contributed"]
license = "MIT/Apache-2.0"
[features]
default = ["json", "static_files"]
# Internal use only.
templates = ["serde", "serde_json", "glob"]
databases = ["r2d2", "rocket_contrib_codegen/database_attribute"]
# User-facing features.
default = ["json", "serve"]
json = ["serde", "serde_json"]
msgpack = ["serde", "rmp-serde"]
tera_templates = ["tera", "templates"]
handlebars_templates = ["handlebars", "templates"]
static_files = []
# Internal use only.
templates = ["serde", "serde_json", "glob"]
serve = []
# Database pooling features.
# Internal use only.
database_pool_codegen = ["rocket_contrib_codegen", "rocket_contrib_codegen/database_attribute"]
database_pool = ["r2d2", "database_pool_codegen"]
# External features.
diesel_postgres_pool = ["database_pool", "diesel/postgres", "diesel/r2d2"]
diesel_sqlite_pool = ["database_pool", "diesel/sqlite", "diesel/r2d2"]
diesel_mysql_pool = ["database_pool", "diesel/mysql", "diesel/r2d2"]
postgres_pool = ["database_pool", "postgres", "r2d2_postgres"]
mysql_pool = ["database_pool", "mysql", "r2d2_mysql"]
sqlite_pool = ["database_pool", "rusqlite", "r2d2_sqlite"]
cypher_pool = ["database_pool", "rusted_cypher", "r2d2_cypher"]
redis_pool = ["database_pool", "redis", "r2d2_redis"]
# The barage of user-facing database features.
diesel_sqlite_pool = ["databases", "diesel/sqlite", "diesel/r2d2"]
diesel_postgres_pool = ["databases", "diesel/postgres", "diesel/r2d2"]
diesel_mysql_pool = ["databases", "diesel/mysql", "diesel/r2d2"]
postgres_pool = ["databases", "postgres", "r2d2_postgres"]
mysql_pool = ["databases", "mysql", "r2d2_mysql"]
sqlite_pool = ["databases", "rusqlite", "r2d2_sqlite"]
cypher_pool = ["databases", "rusted_cypher", "r2d2_cypher"]
redis_pool = ["databases", "redis", "r2d2_redis"]
[dependencies]
# Global dependencies.
rocket = { version = "0.4.0-dev", path = "../../core/lib/" }
log = "0.4"
# UUID dependencies.
uuid = { version = "0.7", optional = true }
# Serialization and templating dependencies.
serde = { version = "1.0", optional = true }
serde_json = { version = "1.0.26", optional = true }
rmp-serde = { version = "^0.13", optional = true }
# Templating dependencies only.
# Templating dependencies.
handlebars = { version = "1.0", optional = true }
glob = { version = "0.2", optional = true }
tera = { version = "0.11", optional = true }
# UUID dependencies.
uuid = { version = "0.7", optional = true }
# Database dependencies
diesel = { version = "1.0", default-features = false, optional = true }
postgres = { version = "0.15", optional = true }

View File

@ -1,4 +1,3 @@
#![doc(cfg(feature = "diesel_sqlite_pool"))]
//! Traits, utilities, and a macro for easy database connection pooling.
//!
//! # Overview
@ -351,50 +350,41 @@
//! implementing the [`Poolable`] trait. See the documentation for [`Poolable`]
//! for more details on how to implement it.
//!
//! [`FromRequest`]: rocket::FromRequest
//! [request guards]: rocket::FromRequest
//! [`FromRequest`]: rocket::request::FromRequest
//! [request guards]: rocket::request::FromRequest
//! [`Poolable`]: databases::Poolable
pub extern crate r2d2;
#[cfg(any(feature = "diesel_sqlite_pool",
feature = "diesel_postgres_pool",
feature = "diesel_mysql_pool"))]
pub extern crate diesel;
use std::collections::BTreeMap;
use std::fmt::{self, Display, Formatter};
use std::marker::{Send, Sized};
use rocket::config::{self, Value};
#[doc(inline)]
pub use rocket_contrib_codegen::database;
use self::r2d2::ManageConnection;
#[cfg(any(feature = "diesel_sqlite_pool", feature = "diesel_postgres_pool", feature = "diesel_mysql_pool"))]
pub extern crate diesel;
#[doc(hidden)] pub use rocket_contrib_codegen::*;
#[cfg(feature = "postgres_pool")]
pub extern crate postgres;
#[cfg(feature = "postgres_pool")]
pub extern crate r2d2_postgres;
#[cfg(feature = "postgres_pool")] pub extern crate postgres;
#[cfg(feature = "postgres_pool")] pub extern crate r2d2_postgres;
#[cfg(feature = "mysql_pool")]
pub extern crate mysql;
#[cfg(feature = "mysql_pool")]
pub extern crate r2d2_mysql;
#[cfg(feature = "mysql_pool")] pub extern crate mysql;
#[cfg(feature = "mysql_pool")] pub extern crate r2d2_mysql;
#[cfg(feature = "sqlite_pool")]
pub extern crate rusqlite;
#[cfg(feature = "sqlite_pool")]
pub extern crate r2d2_sqlite;
#[cfg(feature = "sqlite_pool")] pub extern crate rusqlite;
#[cfg(feature = "sqlite_pool")] pub extern crate r2d2_sqlite;
#[cfg(feature = "cypher_pool")]
pub extern crate rusted_cypher;
#[cfg(feature = "cypher_pool")]
pub extern crate r2d2_cypher;
#[cfg(feature = "cypher_pool")] pub extern crate rusted_cypher;
#[cfg(feature = "cypher_pool")] pub extern crate r2d2_cypher;
#[cfg(feature = "redis_pool")]
pub extern crate redis;
#[cfg(feature = "redis_pool")]
pub extern crate r2d2_redis;
#[cfg(feature = "redis_pool")] pub extern crate redis;
#[cfg(feature = "redis_pool")] pub extern crate r2d2_redis;
/// A structure representing a particular database configuration.
///
@ -447,14 +437,14 @@ pub enum DbError<T> {
/// Error returned on invalid database configurations.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DatabaseConfigError {
pub enum ConfigError {
/// The `databases` configuration key is missing or is empty.
MissingTable,
/// The requested database configuration key is missing from the active
/// configuration.
MissingKey,
/// The configuration associated with the key isn't a
/// [Table](::rocket::config::Table).
/// [`Table`](::rocket::config::Table).
MalformedConfiguration,
/// The required `url` key is missing.
MissingUrl,
@ -488,7 +478,7 @@ pub enum DatabaseConfigError {
/// #
/// # use std::{collections::BTreeMap, mem::drop};
/// # use rocket::{fairing::AdHoc, config::{Config, Environment, Value}};
/// use rocket_contrib::databases::{database_config, DatabaseConfigError};
/// use rocket_contrib::databases::{database_config, ConfigError};
///
/// # let mut databases = BTreeMap::new();
/// #
@ -517,7 +507,7 @@ pub enum DatabaseConfigError {
/// assert_eq!(other_config.url, "mysql://root:root@localhost/database");
///
/// let error = database_config("invalid_db", rocket.config()).unwrap_err();
/// assert_eq!(error, DatabaseConfigError::MissingKey);
/// assert_eq!(error, ConfigError::MissingKey);
/// # }
/// #
/// # Ok(rocket)
@ -526,27 +516,27 @@ pub enum DatabaseConfigError {
pub fn database_config<'a>(
name: &str,
from: &'a config::Config
) -> Result<DatabaseConfig<'a>, DatabaseConfigError> {
) -> Result<DatabaseConfig<'a>, ConfigError> {
// Find the first `databases` config that's a table with a key of 'name'
// equal to `name`.
let connection_config = from.get_table("databases")
.map_err(|_| DatabaseConfigError::MissingTable)?
.map_err(|_| ConfigError::MissingTable)?
.get(name)
.ok_or(DatabaseConfigError::MissingKey)?
.ok_or(ConfigError::MissingKey)?
.as_table()
.ok_or(DatabaseConfigError::MalformedConfiguration)?;
.ok_or(ConfigError::MalformedConfiguration)?;
let maybe_url = connection_config.get("url")
.ok_or(DatabaseConfigError::MissingUrl)?;
.ok_or(ConfigError::MissingUrl)?;
let url = maybe_url.as_str().ok_or(DatabaseConfigError::MalformedUrl)?;
let url = maybe_url.as_str().ok_or(ConfigError::MalformedUrl)?;
let pool_size = connection_config.get("pool_size")
.and_then(Value::as_integer)
.unwrap_or(from.workers as i64);
if pool_size < 1 || pool_size > u32::max_value() as i64 {
return Err(DatabaseConfigError::InvalidPoolSize(pool_size));
return Err(ConfigError::InvalidPoolSize(pool_size));
}
let mut extras = connection_config.clone();
@ -556,25 +546,25 @@ pub fn database_config<'a>(
Ok(DatabaseConfig { url, pool_size: pool_size as u32, extras: extras })
}
impl<'a> Display for DatabaseConfigError {
impl<'a> Display for ConfigError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
DatabaseConfigError::MissingTable => {
ConfigError::MissingTable => {
write!(f, "A table named `databases` was not found for this configuration")
},
DatabaseConfigError::MissingKey => {
ConfigError::MissingKey => {
write!(f, "An entry in the `databases` table was not found for this key")
},
DatabaseConfigError::MalformedConfiguration => {
ConfigError::MalformedConfiguration => {
write!(f, "The configuration for this database is malformed")
}
DatabaseConfigError::MissingUrl => {
ConfigError::MissingUrl => {
write!(f, "The connection URL is missing for this database")
},
DatabaseConfigError::MalformedUrl => {
ConfigError::MalformedUrl => {
write!(f, "The specified connection URL is malformed")
},
DatabaseConfigError::InvalidPoolSize(invalid_size) => {
ConfigError::InvalidPoolSize(invalid_size) => {
write!(f, "'{}' is not a valid value for `pool_size`", invalid_size)
},
}
@ -782,7 +772,7 @@ impl Poolable for redis::Connection {
mod tests {
use std::collections::BTreeMap;
use rocket::{Config, config::{Environment, Value}};
use super::{DatabaseConfigError::*, database_config};
use super::{ConfigError::*, database_config};
#[test]
fn no_database_entry_in_config_returns_error() {

View File

@ -1,3 +1,6 @@
extern crate serde;
extern crate serde_json;
use std::ops::{Deref, DerefMut};
use std::io::{self, Read};
@ -7,25 +10,32 @@ use rocket::data::{Outcome, Transform, Transform::*, Transformed, Data, FromData
use rocket::response::{self, Responder, content};
use rocket::http::Status;
use serde::{Serialize, Serializer};
use serde::de::{Deserialize, Deserializer};
use serde_json;
use self::serde::{Serialize, Serializer};
use self::serde::de::{Deserialize, Deserializer};
/// The JSON type: implements `FromData` and `Responder`, allowing you to easily
/// consume and respond with JSON.
#[doc(hidden)]
pub use self::serde_json::{json_internal, json_internal_vec};
/// The JSON type: implements [`FromData`] and [`Responder`], allowing you to
/// easily consume and respond with JSON.
///
/// ## Receiving JSON
///
/// If you're receiving JSON data, simply add a `data` parameter to your route
/// arguments and ensure the type of the parameter is a `Json<T>`, where `T` is
/// some type you'd like to parse from JSON. `T` must implement `Deserialize` or
/// `DeserializeOwned` from [`serde`](https://github.com/serde-rs/json). The
/// data is parsed from the HTTP request body.
/// some type you'd like to parse from JSON. `T` must implement [`Deserialize`]
/// or from [`serde`]. The data is parsed from the HTTP request body.
///
/// ```rust,ignore
/// #[post("/users/", format = "json", data = "<user>")]
/// ```rust
/// # #![feature(proc_macro_hygiene, decl_macro)]
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// # type User = usize;
/// use rocket_contrib::json::Json;
///
/// #[post("/users", format = "json", data = "<user>")]
/// fn new_user(user: Json<User>) {
/// ...
/// /* ... */
/// }
/// ```
///
@ -37,14 +47,20 @@ use serde_json;
/// ## Sending JSON
///
/// If you're responding with JSON data, return a `Json<T>` type, where `T`
/// implements `Serialize` from [Serde](https://github.com/serde-rs/json). The
/// content type of the response is set to `application/json` automatically.
/// implements [`Serialize`] from [`serde`]. The content type of the response is
/// set to `application/json` automatically.
///
/// ```rust
/// # #![feature(proc_macro_hygiene, decl_macro)]
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// # type User = usize;
/// use rocket_contrib::json::Json;
///
/// ```rust,ignore
/// #[get("/users/<id>")]
/// fn user(id: usize) -> Json<User> {
/// let user_from_id = User::from(id);
/// ...
/// /* ... */
/// Json(user_from_id)
/// }
/// ```
@ -70,7 +86,7 @@ impl<T> Json<T> {
///
/// # Example
/// ```rust
/// # use rocket_contrib::Json;
/// # use rocket_contrib::json::Json;
/// let string = "Hello".to_string();
/// let my_json = Json(string);
/// assert_eq!(my_json.into_inner(), "Hello".to_string());
@ -183,7 +199,7 @@ impl<T> DerefMut for Json<T> {
/// # #![feature(proc_macro_hygiene, decl_macro)]
/// # #[macro_use] extern crate rocket;
/// # #[macro_use] extern crate rocket_contrib;
/// use rocket_contrib::JsonValue;
/// use rocket_contrib::json::JsonValue;
///
/// #[get("/json")]
/// fn get_json() -> JsonValue {
@ -265,14 +281,14 @@ impl<'a> Responder<'a> for JsonValue {
/// #[macro_use] extern crate rocket_contrib;
/// ```
///
/// The return type of a `json!` invocation is [`JsonValue`]. A value created
/// with this macro can be returned from a handler as follows:
/// The return type of a `json!` invocation is [`JsonValue`](json::JsonValue). A
/// value created with this macro can be returned from a handler as follows:
///
/// ```rust
/// # #![feature(proc_macro_hygiene, decl_macro)]
/// # #[macro_use] extern crate rocket;
/// # #[macro_use] extern crate rocket_contrib;
/// use rocket_contrib::JsonValue;
/// use rocket_contrib::json::JsonValue;
///
/// #[get("/json")]
/// fn get_json() -> JsonValue {
@ -283,9 +299,9 @@ impl<'a> Responder<'a> for JsonValue {
/// }
/// ```
///
/// The `Responder` implementation for `JsonValue` serializes the value into a
/// JSON string and sets it as the body of the response with a `Content-Type` of
/// `application/json`.
/// The [`Responder`](rocket::response::Responder) implementation for
/// `JsonValue` serializes the value into a JSON string and sets it as the body
/// of the response with a `Content-Type` of `application/json`.
///
/// # Examples
///
@ -358,6 +374,6 @@ impl<'a> Responder<'a> for JsonValue {
#[macro_export]
macro_rules! json {
($($json:tt)+) => {
$crate::JsonValue(json_internal!($($json)+))
$crate::json::JsonValue($crate::json::json_internal!($($json)+))
};
}

View File

@ -16,13 +16,13 @@
//! common modules exposed by default. The present feature list is below, with
//! an asterisk next to the features that are enabled by default:
//!
//! * [json*](Json)
//! * [static_files*](static_files)
//! * [msgpack](MsgPack)
//! * [handlebars_templates](Template)
//! * [tera_templates](Template)
//! * [uuid](Uuid)
//! * [${database}_pool](databases)
//! * [json*](type@json) - JSON (de)serialization
//! * [serve*](serve) - Static File Serving
//! * [msgpack](msgpack) - MessagePack (de)serialization
//! * [handlebars_templates](templates) - Handlebars Templating
//! * [tera_templates](templates) - Tera Templating
//! * [uuid](uuid) - UUID (de)serialization
//! * [${database}_pool](databases) - Database Configuration and Pooling
//!
//! The recommend way to include features from this crate via Cargo in your
//! project is by adding a `[dependencies.rocket_contrib]` section to your
@ -42,59 +42,14 @@
#[allow(unused_imports)] #[macro_use] extern crate log;
#[allow(unused_imports)] #[macro_use] extern crate rocket;
#[cfg(feature = "serde")]
extern crate serde;
#[cfg(feature="json")] #[macro_use] pub mod json;
#[cfg(feature="serve")] pub mod serve;
#[cfg(feature="msgpack")] pub mod msgpack;
#[cfg(feature="templates")] pub mod templates;
#[cfg(feature="uuid")] pub mod uuid;
#[cfg(feature="databases")] pub mod databases;
#[cfg(feature = "json")]
extern crate serde_json;
#[cfg(feature = "json")]
pub use serde_json::{json_internal, json_internal_vec};
#[cfg(feature = "handlebars_templates")]
pub extern crate handlebars;
#[cfg(feature = "tera_templates")]
pub extern crate tera;
#[cfg(feature = "json")]
#[cfg_attr(feature = "json", macro_use)]
#[doc(hidden)]
pub mod json;
#[cfg(feature = "json")]
pub use json::{Json, JsonError, JsonValue};
#[cfg(feature = "msgpack")]
#[doc(hidden)]
pub mod msgpack;
#[cfg(feature = "msgpack")]
pub use msgpack::{MsgPack, MsgPackError};
#[cfg(feature = "templates")]
mod templates;
#[cfg(feature = "templates")]
pub use templates::{Engines, Template, TemplateMetadata};
#[cfg(feature = "uuid")]
mod uuid;
#[cfg(feature = "uuid")]
pub use uuid::{Uuid, UuidParseError};
#[cfg(feature = "static_files")]
pub mod static_files;
#[cfg(feature = "database_pool")]
pub mod databases;
#[cfg(feature = "database_pool_codegen")]
#[allow(unused_imports)]
#[macro_use]
#[cfg(feature="databases")]
extern crate rocket_contrib_codegen;
#[cfg(feature = "database_pool_codegen")]
#[doc(hidden)]
pub use rocket_contrib_codegen::*;

View File

@ -1,3 +1,4 @@
extern crate serde;
extern crate rmp_serde;
use std::ops::{Deref, DerefMut};
@ -9,31 +10,28 @@ use rocket::data::{Outcome, Transform, Transform::*, Transformed, Data, FromData
use rocket::response::{self, Responder, Response};
use rocket::http::Status;
use serde::Serialize;
use serde::de::Deserialize;
use self::serde::Serialize;
use self::serde::de::Deserialize;
pub use self::rmp_serde::decode::Error as MsgPackError;
pub use self::rmp_serde::decode::Error;
/// The `MsgPack` type: implements `FromData` and `Responder`, allowing you to
/// easily consume and respond with MessagePack data.
/// The `MsgPack` type: implements [`FromData`] and [`Responder`], allowing you
/// to easily consume and respond with MessagePack data.
///
/// ## Receiving MessagePack
///
/// If you're receiving MessagePack data, simply add a `data` parameter to your
/// route arguments and ensure the type of the parameter is a `MsgPack<T>`,
/// where `T` is some type you'd like to parse from MessagePack. `T` must
/// implement `Deserialize` or `DeserializeOwned` from
/// [`serde`](https://github.com/serde-rs/serde). The data is parsed from the
/// HTTP request body.
/// implement [`Deserialize`] from [`serde`]. The data is parsed from the HTTP
/// request body.
///
/// ```rust
/// # #![feature(proc_macro_hygiene, decl_macro)]
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// # type User = usize;
/// # fn main() { }
/// #
/// use rocket_contrib::MsgPack;
/// use rocket_contrib::msgpack::MsgPack;
///
/// #[post("/users", format = "msgpack", data = "<user>")]
/// fn new_user(user: MsgPack<User>) {
@ -49,18 +47,15 @@ pub use self::rmp_serde::decode::Error as MsgPackError;
/// ## Sending MessagePack
///
/// If you're responding with MessagePack data, return a `MsgPack<T>` type,
/// where `T` implements `Serialize` from
/// [serde](https://github.com/serde-rs/serde). The content type of the response
/// is set to `application/msgpack` automatically.
/// where `T` implements [`Serialize`] from [`serde`]. The content type of the
/// response is set to `application/msgpack` automatically.
///
/// ```rust
/// # #![feature(proc_macro_hygiene, decl_macro)]
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// # type User = usize;
/// # fn main() { }
/// #
/// use rocket_contrib::MsgPack;
/// use rocket_contrib::msgpack::MsgPack;
///
/// #[get("/users/<id>")]
/// fn user(id: usize) -> MsgPack<User> {
@ -92,7 +87,7 @@ impl<T> MsgPack<T> {
/// # Example
///
/// ```rust
/// # use rocket_contrib::MsgPack;
/// # use rocket_contrib::msgpack::MsgPack;
/// let string = "Hello".to_string();
/// let my_msgpack = MsgPack(string);
/// assert_eq!(my_msgpack.into_inner(), "Hello".to_string());
@ -107,7 +102,7 @@ impl<T> MsgPack<T> {
const LIMIT: u64 = 1 << 20;
impl<'a, T: Deserialize<'a>> FromData<'a> for MsgPack<T> {
type Error = MsgPackError;
type Error = Error;
type Owned = Vec<u8>;
type Borrowed = [u8];
@ -116,12 +111,12 @@ impl<'a, T: Deserialize<'a>> FromData<'a> for MsgPack<T> {
let size_limit = r.limits().get("msgpack").unwrap_or(LIMIT);
match d.open().take(size_limit).read_to_end(&mut buf) {
Ok(_) => Borrowed(Success(buf)),
Err(e) => Borrowed(Failure((Status::BadRequest, MsgPackError::InvalidDataRead(e))))
Err(e) => Borrowed(Failure((Status::BadRequest, Error::InvalidDataRead(e))))
}
}
fn from_data(_: &Request, o: Transformed<'a, Self>) -> Outcome<Self, Self::Error> {
use self::MsgPackError::*;
use self::Error::*;
let buf = o.borrowed()?;
match rmp_serde::from_slice(&buf) {

View File

@ -46,7 +46,7 @@ impl Options {
/// # Example
///
/// ```rust
/// use rocket_contrib::static_files::Options;
/// use rocket_contrib::serve::Options;
///
/// let index_request = Options::Index | Options::DotFiles;
/// assert!(index_request.contains(Options::Index));
@ -96,7 +96,7 @@ impl ::std::ops::BitOr for Options {
/// ```rust
/// # extern crate rocket;
/// # extern crate rocket_contrib;
/// use rocket_contrib::static_files::StaticFiles;
/// use rocket_contrib::serve::StaticFiles;
///
/// fn main() {
/// # if false {
@ -122,7 +122,7 @@ impl ::std::ops::BitOr for Options {
/// ```rust
/// # extern crate rocket;
/// # extern crate rocket_contrib;
/// use rocket_contrib::static_files::StaticFiles;
/// use rocket_contrib::serve::StaticFiles;
///
/// fn main() {
/// # if false {
@ -151,7 +151,7 @@ impl StaticFiles {
/// ```rust
/// # extern crate rocket;
/// # extern crate rocket_contrib;
/// use rocket_contrib::static_files::StaticFiles;
/// use rocket_contrib::serve::StaticFiles;
///
/// fn main() {
/// # if false {
@ -177,7 +177,7 @@ impl StaticFiles {
/// ```rust
/// # extern crate rocket;
/// # extern crate rocket_contrib;
/// use rocket_contrib::static_files::{StaticFiles, Options};
/// use rocket_contrib::serve::{StaticFiles, Options};
///
/// fn main() {
/// # if false {

View File

@ -1,18 +1,17 @@
use std::path::{Path, PathBuf};
use std::collections::HashMap;
use super::{Engines, TemplateInfo};
use super::glob;
use templates::{glob, Engines, TemplateInfo};
use rocket::http::ContentType;
pub struct Context {
crate struct Context {
/// The root of the template directory.
pub root: PathBuf,
crate root: PathBuf,
/// Mapping from template name to its information.
pub templates: HashMap<String, TemplateInfo>,
crate templates: HashMap<String, TemplateInfo>,
/// Loaded template engines
pub engines: Engines,
crate engines: Engines,
}
impl Context {

View File

@ -1,19 +1,17 @@
use std::collections::HashMap;
use super::serde::Serialize;
use super::TemplateInfo;
use templates::{TemplateInfo, serde::Serialize};
#[cfg(feature = "tera_templates")] use super::tera_templates::Tera;
#[cfg(feature = "handlebars_templates")] use super::handlebars_templates::Handlebars;
#[cfg(feature = "tera_templates")] use templates::tera::Tera;
#[cfg(feature = "handlebars_templates")] use templates::handlebars::Handlebars;
pub trait Engine: Send + Sync + 'static {
crate trait Engine: Send + Sync + 'static {
const EXT: &'static str;
fn init(templates: &[(&str, &TemplateInfo)]) -> Option<Self> where Self: Sized;
fn render<C: Serialize>(&self, name: &str, context: C) -> Option<String>;
}
#[doc(cfg(feature = "tera_templates"))]
/// A structure exposing access to templating engines.
///
/// Calling methods on the exposed template engine types may require importing
@ -21,13 +19,14 @@ pub trait Engine: Send + Sync + 'static {
/// imported from the reexported crate at the root of `rocket_contrib` to avoid
/// version mismatches. For instance, when registering a Tera filter, the
/// [`tera::Value`] and [`tera::Result`] types are required. Import them from
/// `rocket_contrib::tera`. The example below illustrates this:
/// `rocket_contrib::templates::tera`. The example below illustrates this:
///
/// ```rust
/// # #[cfg(feature = "tera_templates")] {
/// use std::collections::HashMap;
///
/// use rocket_contrib::{Template, Engines};
/// use rocket_contrib::tera::{self, Value};
/// use rocket_contrib::templates::{Template, Engines};
/// use rocket_contrib::templates::tera::{self, Value};
///
/// fn my_filter(value: Value, _: HashMap<String, Value>) -> tera::Result<Value> {
/// # /*
@ -38,25 +37,22 @@ pub trait Engine: Send + Sync + 'static {
/// Template::custom(|engines: &mut Engines| {
/// engines.tera.register_filter("my_filter", my_filter);
/// });
/// # }
/// ```
///
/// [`tera::Value`]: ::tera::Value
/// [`tera::Result`]: ::tera::Result
/// [`tera::Value`]: ::templates::tera::Value
/// [`tera::Result`]: ::templates::tera::Result
pub struct Engines {
#[cfg(feature = "tera_templates")]
/// A [`Tera`] structure. This field is only available when the
/// A `Tera` templating engine. This field is only available when the
/// `tera_templates` feature is enabled. When calling methods on the `Tera`
/// instance, ensure you use types imported from `rocket_contrib::tera` to
/// avoid version mismatches.
///
/// [`Tera`]: tera::Tera
/// instance, ensure you use types imported from
/// `rocket_contrib::templates::tera` to avoid version mismatches.
#[cfg(feature = "tera_templates")]
pub tera: Tera,
/// A [`Handlebars`] structure. This field is only available when the
/// The Handlebars templating engine. This field is only available when the
/// `handlebars_templates` feature is enabled. When calling methods on the
/// `Tera` instance, ensure you use types
/// imported from `rocket_contrib::handlebars` to avoid version mismatches.
///
/// [`Handlebars`]: handlebars::Handlebars
/// `Tera` instance, ensure you use types imported from
/// `rocket_contrib::templates::handlebars` to avoid version mismatches.
#[cfg(feature = "handlebars_templates")]
pub handlebars: Handlebars,
}

View File

@ -1,28 +1,26 @@
use super::DEFAULT_TEMPLATE_DIR;
use super::context::Context;
use super::engine::Engines;
use templates::{DEFAULT_TEMPLATE_DIR, Context, Engines};
use rocket::Rocket;
use rocket::config::ConfigError;
use rocket::fairing::{Fairing, Info, Kind};
pub use self::context::ContextManager;
crate use self::context::ContextManager;
#[cfg(not(debug_assertions))]
mod context {
use std::ops::Deref;
use super::Context;
use templates::Context;
/// Wraps a Context. With `cfg(debug_assertions)` active, this structure
/// additionally provides a method to reload the context at runtime.
pub struct ContextManager(Context);
crate struct ContextManager(Context);
impl ContextManager {
pub fn new(ctxt: Context) -> ContextManager {
crate fn new(ctxt: Context) -> ContextManager {
ContextManager(ctxt)
}
pub fn context<'a>(&'a self) -> impl Deref<Target=Context> + 'a {
crate fn context<'a>(&'a self) -> impl Deref<Target=Context> + 'a {
&self.0
}
}
@ -36,13 +34,13 @@ mod context {
use std::sync::{RwLock, Mutex};
use std::sync::mpsc::{channel, Receiver};
use super::{Context, Engines};
use templates::{Context, Engines};
use self::notify::{raw_watcher, RawEvent, RecommendedWatcher, RecursiveMode, Watcher};
/// Wraps a Context. With `cfg(debug_assertions)` active, this structure
/// additionally provides a method to reload the context at runtime.
pub struct ContextManager {
crate struct ContextManager {
/// The current template context, inside an RwLock so it can be updated.
context: RwLock<Context>,
/// A filesystem watcher and the receive queue for its events.
@ -50,7 +48,7 @@ mod context {
}
impl ContextManager {
pub fn new(ctxt: Context) -> ContextManager {
crate fn new(ctxt: Context) -> ContextManager {
let (tx, rx) = channel();
let watcher = if let Ok(mut watcher) = raw_watcher(tx) {
@ -73,7 +71,7 @@ mod context {
}
}
pub fn context<'a>(&'a self) -> impl Deref<Target=Context> + 'a {
crate fn context<'a>(&'a self) -> impl Deref<Target=Context> + 'a {
self.context.read().unwrap()
}
@ -85,7 +83,7 @@ mod context {
/// have been changes since the last reload, all templates are
/// reinitialized from disk and the user's customization callback is run
/// again.
pub fn reload_if_needed<F: Fn(&mut Engines)>(&self, custom_callback: F) {
crate fn reload_if_needed<F: Fn(&mut Engines)>(&self, custom_callback: F) {
self.watcher.as_ref().map(|w| {
let rx_lock = w.lock().expect("receive queue lock");
let mut changed = false;
@ -117,7 +115,7 @@ pub struct TemplateFairing {
/// The user-provided customization callback, allowing the use of
/// functionality specific to individual template engines. In debug mode,
/// this callback might be run multiple times as templates are reloaded.
pub(crate) custom_callback: Box<Fn(&mut Engines) + Send + Sync + 'static>,
crate custom_callback: Box<Fn(&mut Engines) + Send + Sync + 'static>,
}
impl Fairing for TemplateFairing {

View File

@ -1,9 +1,7 @@
extern crate handlebars;
use templates::serde::Serialize;
use templates::{Engine, TemplateInfo};
use super::serde::Serialize;
use super::{Engine, TemplateInfo};
pub use self::handlebars::Handlebars;
pub use templates::handlebars::Handlebars;
impl Engine for Handlebars {
const EXT: &'static str = "hbs";

View File

@ -2,43 +2,23 @@ use rocket::{Request, State, Outcome};
use rocket::http::Status;
use rocket::request::{self, FromRequest};
use super::ContextManager;
use templates::ContextManager;
/// Implements [`FromRequest`] for dynamiclly querying template metadata.
/// Request guard for dynamiclly querying template metadata.
///
/// # Usage
///
/// First, ensure that the template [fairing](rocket::fairing),
/// [`Template::fairing()`](::Template::fairing()) is attached to your Rocket
/// application:
///
/// ```rust
/// # extern crate rocket;
/// # extern crate rocket_contrib;
/// #
/// use rocket_contrib::Template;
///
/// fn main() {
/// rocket::ignite()
/// .attach(Template::fairing())
/// // ...
/// # ;
/// }
/// ```
///
/// The `TemplateMetadata` type implements Rocket's `FromRequest` trait, so it
/// can be used as a request guard in any request handler.
/// The `Metadata` type implements Rocket's [`FromRequest`] trait, so it can be
/// used as a request guard in any request handler.
///
/// ```rust
/// # #![feature(proc_macro_hygiene, decl_macro)]
/// # #[macro_use] extern crate rocket;
/// # #[macro_use] extern crate rocket_contrib;
/// # fn main() { }
/// #
/// use rocket_contrib::{Template, TemplateMetadata};
/// use rocket_contrib::templates::{Template, Metadata};
///
/// #[get("/")]
/// fn homepage(metadata: TemplateMetadata) -> Template {
/// fn homepage(metadata: Metadata) -> Template {
/// # use std::collections::HashMap;
/// # let context: HashMap<String, String> = HashMap::new();
/// // Conditionally render a template if it's available.
@ -48,19 +28,27 @@ use super::ContextManager;
/// Template::render("fallback", &context)
/// }
/// }
///
///
/// fn main() {
/// rocket::ignite()
/// .attach(Template::fairing())
/// // ...
/// # ;
/// }
/// ```
pub struct TemplateMetadata<'a>(&'a ContextManager);
pub struct Metadata<'a>(&'a ContextManager);
impl<'a> TemplateMetadata<'a> {
impl<'a> Metadata<'a> {
/// Returns `true` if the template with name `name` was loaded at start-up
/// time. Otherwise, returns `false`.
///
/// # Example
///
/// ```rust
/// use rocket_contrib::TemplateMetadata;
/// use rocket_contrib::templates::Metadata;
///
/// fn handler(metadata: TemplateMetadata) {
/// fn handler(metadata: Metadata) {
/// // Returns `true` if the template with name `"name"` was loaded.
/// let loaded = metadata.contains_template("name");
/// }
@ -73,13 +61,13 @@ impl<'a> TemplateMetadata<'a> {
/// Retrieves the template metadata. If a template fairing hasn't been attached,
/// an error is printed and an empty `Err` with status `InternalServerError`
/// (`500`) is returned.
impl<'a, 'r> FromRequest<'a, 'r> for TemplateMetadata<'a> {
impl<'a, 'r> FromRequest<'a, 'r> for Metadata<'a> {
type Error = ();
fn from_request(request: &'a Request) -> request::Outcome<Self, ()> {
request.guard::<State<ContextManager>>()
.succeeded()
.and_then(|cm| Some(Outcome::Success(TemplateMetadata(cm.inner()))))
.and_then(|cm| Some(Outcome::Success(Metadata(cm.inner()))))
.unwrap_or_else(|| {
error_!("Uninitialized template context: missing fairing.");
info_!("To use templates, you must attach `Template::fairing()`.");

View File

@ -2,7 +2,10 @@ extern crate serde;
extern crate serde_json;
extern crate glob;
#[cfg(feature = "tera_templates")] pub extern crate tera;
#[cfg(feature = "tera_templates")] mod tera_templates;
#[cfg(feature = "handlebars_templates")] pub extern crate handlebars;
#[cfg(feature = "handlebars_templates")] mod handlebars_templates;
mod engine;
@ -11,11 +14,12 @@ mod context;
mod metadata;
pub use self::engine::Engines;
pub use self::metadata::TemplateMetadata;
pub use self::metadata::Metadata;
crate use self::context::Context;
crate use self::fairing::ContextManager;
use self::engine::Engine;
use self::fairing::{TemplateFairing, ContextManager};
use self::context::Context;
use self::fairing::TemplateFairing;
use self::serde::Serialize;
use self::serde_json::{Value, to_value};
use self::glob::glob;
@ -99,14 +103,12 @@ const DEFAULT_TEMPLATE_DIR: &str = "templates";
/// application:
///
/// ```rust
/// extern crate rocket;
/// extern crate rocket_contrib;
///
/// use rocket_contrib::Template;
/// # extern crate rocket;
/// # extern crate rocket_contrib;
/// use rocket_contrib::templates::Template;
///
/// fn main() {
/// rocket::ignite()
/// // ...
/// .attach(Template::fairing())
/// // ...
/// # ;
@ -116,10 +118,16 @@ const DEFAULT_TEMPLATE_DIR: &str = "templates";
/// The `Template` type implements Rocket's [`Responder`] trait, so it can be
/// returned from a request handler directly:
///
/// ```rust,ignore
/// ```rust
/// # #![feature(proc_macro_hygiene, decl_macro)]
/// # #[macro_use] extern crate rocket;
/// # #[macro_use] extern crate rocket_contrib;
/// # fn context() { }
/// use rocket_contrib::templates::Template;
///
/// #[get("/")]
/// fn index() -> Template {
/// let context = ...;
/// let context = context();
/// Template::render("index", &context)
/// }
/// ```
@ -136,7 +144,7 @@ pub struct Template {
}
#[derive(Debug)]
pub struct TemplateInfo {
crate struct TemplateInfo {
/// The complete path, including `template_dir`, to this template.
path: PathBuf,
/// The extension for the engine of this template.
@ -166,7 +174,7 @@ impl Template {
/// extern crate rocket;
/// extern crate rocket_contrib;
///
/// use rocket_contrib::Template;
/// use rocket_contrib::templates::Template;
///
/// fn main() {
/// rocket::ignite()
@ -192,7 +200,7 @@ impl Template {
/// extern crate rocket;
/// extern crate rocket_contrib;
///
/// use rocket_contrib::Template;
/// use rocket_contrib::templates::Template;
///
/// fn main() {
/// rocket::ignite()
@ -218,7 +226,7 @@ impl Template {
///
/// ```rust
/// use std::collections::HashMap;
/// use rocket_contrib::Template;
/// use rocket_contrib::templates::Template;
///
/// // Create a `context`. Here, just an empty `HashMap`.
/// let mut context = HashMap::new();
@ -235,9 +243,9 @@ impl Template {
/// Render the template named `name` with the context `context` into a
/// `String`. This method should **not** be used in any running Rocket
/// application. This method should only be used during testing to
/// validate `Template` responses. For other uses, use
/// [`render`](#method.render) instead.
/// application. This method should only be used during testing to validate
/// `Template` responses. For other uses, use [`render()`](#method.render)
/// instead.
///
/// The `context` can be of any type that implements `Serialize`. This is
/// typically a `HashMap` or a custom `struct`.
@ -253,7 +261,7 @@ impl Template {
/// # extern crate rocket_contrib;
/// use std::collections::HashMap;
///
/// use rocket_contrib::Template;
/// use rocket_contrib::templates::Template;
/// use rocket::local::Client;
///
/// fn main() {

View File

@ -1,9 +1,7 @@
extern crate tera;
use templates::serde::Serialize;
use templates::{Engine, TemplateInfo};
use super::serde::Serialize;
use super::{Engine, TemplateInfo};
pub use self::tera::Tera;
pub use templates::tera::Tera;
impl Engine for Tera {
const EXT: &'static str = "tera";

View File

@ -1,4 +1,4 @@
extern crate uuid as uuid_ext;
pub extern crate uuid as uuid_crate;
use std::fmt;
use std::str::FromStr;
@ -7,7 +7,7 @@ use std::ops::Deref;
use rocket::request::{FromParam, FromFormValue};
use rocket::http::RawStr;
pub use self::uuid_ext::parser::ParseError as UuidParseError;
pub use self::uuid_crate::parser::ParseError;
/// Implements [`FromParam`] and [`FromFormValue`] for accepting UUID values
/// from the [`uuid`] crate.
@ -26,7 +26,12 @@ pub use self::uuid_ext::parser::ParseError as UuidParseError;
///
/// You can use the `Uuid` type directly as a target of a dynamic parameter:
///
/// ```rust,ignore
/// ```rust
/// # #![feature(proc_macro_hygiene, decl_macro)]
/// # #[macro_use] extern crate rocket;
/// # #[macro_use] extern crate rocket_contrib;
/// use rocket_contrib::uuid::Uuid;
///
/// #[get("/users/<id>")]
/// fn user(id: Uuid) -> String {
/// format!("We found: {}", id)
@ -35,18 +40,18 @@ pub use self::uuid_ext::parser::ParseError as UuidParseError;
///
/// You can also use the `Uuid` as a form value, including in query strings:
///
/// ```rust,ignore
/// #[derive(FromForm)]
/// struct UserQuery {
/// id: Uuid
/// }
/// ```rust
/// # #![feature(proc_macro_hygiene, decl_macro)]
/// # #[macro_use] extern crate rocket;
/// # #[macro_use] extern crate rocket_contrib;
/// use rocket_contrib::uuid::Uuid;
///
/// #[post("/user?<user_query>")]
/// fn user(user_query: UserQuery) -> String {
/// format!("User ID: {}", user_query.id)
/// #[get("/user?<id>")]
/// fn user(id: Uuid) -> String {
/// format!("User ID: {}", id)
/// }
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct Uuid(uuid_ext::Uuid);
pub struct Uuid(uuid_crate::Uuid);
impl Uuid {
/// Consumes the Uuid wrapper, returning the underlying `Uuid` type.
@ -54,17 +59,21 @@ impl Uuid {
/// # Example
/// ```rust
/// # extern crate rocket_contrib;
/// # extern crate uuid;
/// # use std::str::FromStr;
/// # fn main() {
/// use rocket_contrib::uuid::{uuid_crate, Uuid};
///
/// let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2";
/// let real_uuid = uuid::Uuid::from_str(uuid_str).unwrap();
/// let my_inner_uuid = rocket_contrib::Uuid::from_str(uuid_str).unwrap().into_inner();
/// let real_uuid = uuid_crate::Uuid::from_str(uuid_str).unwrap();
/// let my_inner_uuid = Uuid::from_str(uuid_str)
/// .expect("valid UUID string")
/// .into_inner();
///
/// assert_eq!(real_uuid, my_inner_uuid);
/// # }
/// ```
#[inline(always)]
pub fn into_inner(self) -> uuid_ext::Uuid {
pub fn into_inner(self) -> uuid_crate::Uuid {
self.0
}
}
@ -77,10 +86,10 @@ impl fmt::Display for Uuid {
}
impl<'a> FromParam<'a> for Uuid {
type Error = UuidParseError;
type Error = ParseError;
/// A value is successfully parsed if `param` is a properly formatted Uuid.
/// Otherwise, a `UuidParseError` is returned.
/// Otherwise, a `ParseError` is returned.
#[inline(always)]
fn from_param(param: &'a RawStr) -> Result<Uuid, Self::Error> {
param.parse()
@ -99,7 +108,7 @@ impl<'v> FromFormValue<'v> for Uuid {
}
impl FromStr for Uuid {
type Err = UuidParseError;
type Err = ParseError;
#[inline]
fn from_str(s: &str) -> Result<Uuid, Self::Err> {
@ -108,23 +117,23 @@ impl FromStr for Uuid {
}
impl Deref for Uuid {
type Target = uuid_ext::Uuid;
type Target = uuid_crate::Uuid;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl PartialEq<uuid_ext::Uuid> for Uuid {
impl PartialEq<uuid_crate::Uuid> for Uuid {
#[inline(always)]
fn eq(&self, other: &uuid_ext::Uuid) -> bool {
fn eq(&self, other: &uuid_crate::Uuid) -> bool {
self.0.eq(other)
}
}
#[cfg(test)]
mod test {
use super::uuid_ext;
use super::uuid_crate;
use super::Uuid;
use super::FromParam;
use super::FromStr;
@ -147,8 +156,8 @@ mod test {
fn test_into_inner() {
let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2";
let uuid_wrapper = Uuid::from_param(uuid_str.into()).unwrap();
let real_uuid: uuid_ext::Uuid = uuid_str.parse().unwrap();
let inner_uuid: uuid_ext::Uuid = uuid_wrapper.into_inner();
let real_uuid: uuid_crate::Uuid = uuid_str.parse().unwrap();
let inner_uuid: uuid_crate::Uuid = uuid_wrapper.into_inner();
assert_eq!(real_uuid, inner_uuid)
}
@ -156,7 +165,7 @@ mod test {
fn test_partial_eq() {
let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2";
let uuid_wrapper = Uuid::from_param(uuid_str.into()).unwrap();
let real_uuid: uuid_ext::Uuid = uuid_str.parse().unwrap();
let real_uuid: uuid_crate::Uuid = uuid_str.parse().unwrap();
assert_eq!(uuid_wrapper, real_uuid)
}

View File

@ -1,7 +1,7 @@
extern crate rocket;
extern crate rocket_contrib;
#[cfg(feature = "databases")]
#[cfg(all(feature = "diesel_sqlite_pool", feature = "diesel_postgres_pool"))]
mod databases_tests {
use rocket_contrib::databases::{database, diesel};

View File

@ -3,13 +3,13 @@
extern crate rocket;
extern crate rocket_contrib;
#[cfg(feature = "static_files")]
mod static_files_tests {
#[cfg(feature = "static")]
mod static_tests {
use std::{io::Read, fs::File};
use std::path::{Path, PathBuf};
use rocket::{self, Rocket};
use rocket_contrib::static_files::{StaticFiles, Options};
use rocket_contrib::serve::{StaticFiles, Options};
use rocket::http::Status;
use rocket::local::Client;

View File

@ -1,6 +1,9 @@
#![feature(proc_macro_hygiene, decl_macro)]
#[cfg(feature = "templates")]
#[macro_use] extern crate rocket;
#[cfg(feature = "templates")]
extern crate rocket_contrib;
#[cfg(feature = "templates")]
@ -9,10 +12,10 @@ mod templates_tests {
use rocket::{Rocket, http::RawStr};
use rocket::config::{Config, Environment};
use rocket_contrib::{Template, TemplateMetadata};
use rocket_contrib::templates::{Template, Metadata};
#[get("/<engine>/<name>")]
fn template_check(md: TemplateMetadata, engine: &RawStr, name: &RawStr) -> Option<()> {
fn template_check(md: Metadata, engine: &RawStr, name: &RawStr) -> Option<()> {
match md.contains_template(&format!("{}/{}", engine, name)) {
true => Some(()),
false => None

View File

@ -1,7 +1,7 @@
#![feature(proc_macro_hygiene, decl_macro)]
extern crate rocket_contrib;
#[macro_use] extern crate rocket;
extern crate rocket_contrib;
#[cfg(test)]
mod tests;
@ -11,7 +11,7 @@ use std::collections::HashMap;
use rocket::request::Form;
use rocket::response::Redirect;
use rocket::http::{Cookie, Cookies};
use rocket_contrib::Template;
use rocket_contrib::templates::Template;
#[derive(FromForm)]
struct Message {

View File

@ -3,7 +3,7 @@ use std::collections::HashMap;
use super::rocket;
use rocket::local::Client;
use rocket::http::*;
use rocket_contrib::Template;
use rocket_contrib::templates::Template;
#[test]
fn test_submit() {

View File

@ -8,7 +8,7 @@ extern crate rocket_contrib;
use rocket::Request;
use rocket::response::Redirect;
use rocket_contrib::{Template, handlebars};
use rocket_contrib::templates::{Template, handlebars};
use handlebars::{Helper, Handlebars, Context, RenderContext, Output, HelperResult, JsonRender};

View File

@ -3,7 +3,7 @@ use super::{rocket, TemplateContext};
use rocket::local::{Client, LocalResponse};
use rocket::http::Method::*;
use rocket::http::Status;
use rocket_contrib::Template;
use rocket_contrib::templates::Template;
macro_rules! dispatch {
($method:expr, $path:expr, $test_fn:expr) => ({

View File

@ -6,10 +6,11 @@
#[cfg(test)] mod tests;
use rocket::State;
use rocket_contrib::{Json, JsonValue};
use std::collections::HashMap;
use std::sync::Mutex;
use std::collections::HashMap;
use rocket::State;
use rocket_contrib::json::{Json, JsonValue};
// The type to represent the ID of a message.
type ID = usize;

View File

@ -6,7 +6,7 @@ extern crate rocket_contrib;
#[cfg(test)] mod tests;
use rocket_contrib::MsgPack;
use rocket_contrib::msgpack::MsgPack;
#[derive(Serialize, Deserialize)]
struct Message<'r> {

View File

@ -11,7 +11,7 @@ use rocket::outcome::IntoOutcome;
use rocket::request::{self, Form, FlashMessage, FromRequest, Request};
use rocket::response::{Redirect, Flash};
use rocket::http::{Cookie, Cookies};
use rocket_contrib::Template;
use rocket_contrib::templates::Template;
#[derive(FromForm)]
struct Login {

View File

@ -3,7 +3,7 @@ extern crate rocket_contrib;
#[cfg(test)] mod tests;
use rocket_contrib::static_files::StaticFiles;
use rocket_contrib::serve::StaticFiles;
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", StaticFiles::from("static"))

View File

@ -11,7 +11,7 @@ use std::collections::HashMap;
use rocket::Request;
use rocket::response::Redirect;
use rocket_contrib::Template;
use rocket_contrib::templates::Template;
#[derive(Serialize)]
struct TemplateContext {

View File

@ -2,7 +2,7 @@ use super::rocket;
use rocket::local::{Client, LocalResponse};
use rocket::http::Method::*;
use rocket::http::Status;
use rocket_contrib::Template;
use rocket_contrib::templates::Template;
macro_rules! dispatch {
($method:expr, $path:expr, $test_fn:expr) => ({

View File

@ -20,4 +20,4 @@ rand = "0.5"
[dependencies.rocket_contrib]
path = "../../contrib/lib"
default_features = false
features = ["tera_templates", "diesel_sqlite_pool", "static_files"]
features = ["tera_templates", "diesel_sqlite_pool", "serve"]

View File

@ -14,7 +14,7 @@ use rocket::Rocket;
use rocket::fairing::AdHoc;
use rocket::request::{Form, FlashMessage};
use rocket::response::{Flash, Redirect};
use rocket_contrib::{Template, databases::database, static_files::StaticFiles};
use rocket_contrib::{templates::Template, databases::database, serve::StaticFiles};
use diesel::SqliteConnection;
use task::{Task, Todo};

View File

@ -2,18 +2,18 @@
#[macro_use] extern crate rocket;
#[macro_use] extern crate lazy_static;
extern crate uuid;
extern crate rocket_contrib;
extern crate uuid;
use std::collections::HashMap;
use rocket_contrib::Uuid;
use rocket_contrib::uuid::Uuid;
#[cfg(test)] mod tests;
lazy_static! {
// A small people lookup table for the sake of this example. In a real
// application this could be a database lookup. Notice that we use the
// uuid::Uuid type here and not the rocket_contrib::Uuid type.
// uuid::Uuid type here and not the rocket_contrib::uuid::Uuid type.
static ref PEOPLE: HashMap<uuid::Uuid, &'static str> = {
let mut m = HashMap::new();
let lacy_id = uuid::Uuid::parse_str("7f205202-7ba1-4c39-b2fc-3e630722bf9f").unwrap();
@ -29,7 +29,7 @@ lazy_static! {
#[get("/people/<id>")]
fn people(id: Uuid) -> Result<String, String> {
// Because Uuid implements the Deref trait, we use Deref coercion to convert
// rocket_contrib::Uuid to uuid::Uuid.
// rocket_contrib::uuid::Uuid to uuid::Uuid.
Ok(PEOPLE.get(&id)
.map(|person| format!("We found: {}", person))
.ok_or_else(|| format!("Person not found for UUID: {}", id))?)

View File

@ -85,7 +85,7 @@ if [ "$1" = "--contrib" ]; then
msgpack
tera_templates
handlebars_templates
static_files
serve
diesel_postgres_pool
diesel_sqlite_pool
diesel_mysql_pool