From a78814f1c5285e76bc84b7cbb345e919d4460cb5 Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Fri, 21 May 2021 14:29:43 -0700 Subject: [PATCH] Graduate contrib 'uuid' into core. This has the following nice benefits: * The 'Uuid' wrapper type is gone. * 'Uuid' implements 'UriDisplay', 'FromUriParam'. * The 'serialization' example merges in 'uuid'. Resolves #1299. --- contrib/lib/Cargo.toml | 7 - contrib/lib/src/lib.rs | 2 - contrib/lib/src/uuid.rs | 203 --------------------------- core/http/Cargo.toml | 7 + core/http/src/uri/fmt/uri_display.rs | 14 +- core/lib/Cargo.toml | 2 + core/lib/src/lib.rs | 2 + core/lib/src/serde/mod.rs | 4 + core/lib/src/serde/uuid.rs | 141 +++++++++++++++++++ examples/Cargo.toml | 1 - examples/README.md | 5 +- examples/serialization/Cargo.toml | 2 +- examples/serialization/src/main.rs | 2 + examples/serialization/src/tests.rs | 24 +++- examples/serialization/src/uuid.rs | 29 ++++ examples/uuid/Cargo.toml | 14 -- examples/uuid/src/main.rs | 36 ----- examples/uuid/src/tests.rs | 25 ---- scripts/test.sh | 1 + 19 files changed, 222 insertions(+), 299 deletions(-) delete mode 100644 contrib/lib/src/uuid.rs create mode 100644 core/lib/src/serde/uuid.rs create mode 100644 examples/serialization/src/uuid.rs delete mode 100644 examples/uuid/Cargo.toml delete mode 100644 examples/uuid/src/main.rs delete mode 100644 examples/uuid/src/tests.rs diff --git a/contrib/lib/Cargo.toml b/contrib/lib/Cargo.toml index e513e573..5660ddaf 100644 --- a/contrib/lib/Cargo.toml +++ b/contrib/lib/Cargo.toml @@ -27,7 +27,6 @@ serve = [] compression = ["brotli_compression", "gzip_compression"] brotli_compression = ["brotli"] gzip_compression = ["flate2"] -uuid = ["serde", "_uuid"] # The barage of user-facing database features. diesel_sqlite_pool = ["databases", "diesel/sqlite", "diesel/r2d2"] @@ -69,12 +68,6 @@ r2d2-memcache = { version = "0.6", optional = true } brotli = { version = "3.3", optional = true } flate2 = { version = "1.0", optional = true } -[dependencies._uuid] -package = "uuid" -version = ">=0.7.0, <0.9.0" -optional = true -features = ["serde"] - [dev-dependencies] serde_test = "1.0.114" diff --git a/contrib/lib/src/lib.rs b/contrib/lib/src/lib.rs index 2a05bd5c..944120a3 100644 --- a/contrib/lib/src/lib.rs +++ b/contrib/lib/src/lib.rs @@ -19,7 +19,6 @@ //! * [serve*](serve) - Static File Serving //! * [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 Rocket in your @@ -42,7 +41,6 @@ #[cfg(feature="serve")] pub mod serve; #[cfg(feature="templates")] pub mod templates; -#[cfg(feature="uuid")] pub mod uuid; #[cfg(feature="databases")] pub mod databases; // TODO.async: Migrate compression, reenable this, tests, and add to docs. //#[cfg(any(feature="brotli_compression", feature="gzip_compression"))] pub mod compression; diff --git a/contrib/lib/src/uuid.rs b/contrib/lib/src/uuid.rs deleted file mode 100644 index c269b09e..00000000 --- a/contrib/lib/src/uuid.rs +++ /dev/null @@ -1,203 +0,0 @@ -//! UUID parameter and form value parsing support. -//! -//! See the [`Uuid`] type for further details. -//! -//! # Enabling -//! -//! This module is only available when the `uuid` feature is enabled. Enable it -//! in `Cargo.toml` as follows: -//! -//! ```toml -//! [dependencies.rocket_contrib] -//! version = "0.5.0-dev" -//! default-features = false -//! features = ["uuid"] -//! ``` - -pub extern crate _uuid as extern_uuid; - -use std::fmt; -use std::str::FromStr; -use std::ops::Deref; - -use serde::{Deserialize, Serialize}; - -use rocket::request::FromParam; -use rocket::form::{self, FromFormField, ValueField}; - -/// UUID data and form guard: consume UUID values. -/// -/// `Uuid` implements [`FromParam`] and [`FromFormField`], allowing UUID values -/// to be accepted directly in paths, queries, and forms. -/// -/// # Usage -/// -/// To use, add the `uuid` feature to the `rocket_contrib` dependencies section -/// of your `Cargo.toml`: -/// -/// ```toml -/// [dependencies.rocket_contrib] -/// version = "0.5.0-dev" -/// default-features = false -/// features = ["uuid"] -/// ``` -/// -/// You can use the `Uuid` type directly as a target of a dynamic parameter: -/// -/// ```rust -/// # #[macro_use] extern crate rocket; -/// # #[macro_use] extern crate rocket_contrib; -/// use rocket_contrib::uuid::Uuid; -/// -/// #[get("/users/")] -/// fn user(id: Uuid) -> String { -/// format!("We found: {}", id) -/// } -/// ``` -/// -/// You can also use the `Uuid` as a form value, including in query strings: -/// -/// ```rust -/// # #[macro_use] extern crate rocket; -/// # #[macro_use] extern crate rocket_contrib; -/// use rocket_contrib::uuid::Uuid; -/// -/// #[get("/user?")] -/// fn user(id: Uuid) -> String { -/// format!("User ID: {}", id) -/// } -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)] -#[serde(transparent)] -pub struct Uuid(_uuid::Uuid); - -pub type Error = <_uuid::Uuid as std::str::FromStr>::Err; - -impl Uuid { - /// Consumes the Uuid wrapper, returning the underlying `Uuid` type. - /// - /// # Example - /// ```rust - /// # extern crate rocket_contrib; - /// # use std::str::FromStr; - /// # fn main() { - /// use rocket_contrib::uuid::{extern_uuid, Uuid}; - /// - /// let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2"; - /// let real_uuid = extern_uuid::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::Uuid { - self.0 - } -} - -impl fmt::Display for Uuid { - #[inline(always)] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} - -impl<'a> FromParam<'a> for Uuid { - type Error = Error; - - /// A value is successfully parsed if `param` is a properly formatted Uuid. - /// Otherwise, an error is returned. - #[inline(always)] - fn from_param(param: &'a str) -> Result { - param.parse() - } -} - -impl<'v> FromFormField<'v> for Uuid { - fn from_value(field: ValueField<'v>) -> form::Result<'v, Self> { - Ok(field.value.parse().map_err(form::error::Error::custom)?) - } -} - -impl FromStr for Uuid { - type Err = Error; - - #[inline] - fn from_str(s: &str) -> Result { - s.parse().map(Uuid) - } -} - -impl Deref for Uuid { - type Target = _uuid::Uuid; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl PartialEq<_uuid::Uuid> for Uuid { - #[inline(always)] - fn eq(&self, other: &_uuid::Uuid) -> bool { - self.0.eq(other) - } -} - -#[cfg(test)] -mod test { - use super::Uuid; - use super::FromParam; - use super::FromStr; - - #[test] - fn test_from_str() { - let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2"; - let uuid_wrapper = Uuid::from_str(uuid_str).unwrap(); - assert_eq!(uuid_str, uuid_wrapper.to_string()) - } - - #[test] - fn test_from_param() { - let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2"; - let uuid_wrapper = Uuid::from_param(uuid_str.into()).unwrap(); - assert_eq!(uuid_str, uuid_wrapper.to_string()) - } - - #[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::Uuid = uuid_str.parse().unwrap(); - let inner_uuid: _uuid::Uuid = uuid_wrapper.into_inner(); - assert_eq!(real_uuid, inner_uuid) - } - - #[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::Uuid = uuid_str.parse().unwrap(); - assert_eq!(uuid_wrapper, real_uuid) - } - - #[test] - #[should_panic(expected = "InvalidLength")] - fn test_from_param_invalid() { - let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2p"; - Uuid::from_param(uuid_str.into()).unwrap(); - } - - #[test] - fn test_ser_de() { - // The main reason for this test is to test that UUID only serializes as - // a string token, not anything else. Like a Struct with a named field... - use serde_test::{Token, assert_tokens, Configure}; - let uuid: Uuid = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2".parse().unwrap(); - - assert_tokens(&uuid.readable(), &[ - Token::Str("c1aa1e3b-9614-4895-9ebd-705255fa5bc2"), - ]); - } -} diff --git a/core/http/Cargo.toml b/core/http/Cargo.toml index dd790853..7fa3c214 100644 --- a/core/http/Cargo.toml +++ b/core/http/Cargo.toml @@ -19,6 +19,7 @@ default = [] tls = ["tokio-rustls"] private-cookies = ["cookie/private", "cookie/key-expansion"] serde = ["uncased/with-serde-alloc", "_serde"] +uuid = ["_uuid"] [dependencies] smallvec = "1.0" @@ -56,5 +57,11 @@ optional = true default-features = false features = ["std"] +[dependencies._uuid] +package = "uuid" +version = "0.8" +optional = true +default-features = false + [dev-dependencies] rocket = { version = "0.5.0-dev", path = "../lib" } diff --git a/core/http/src/uri/fmt/uri_display.rs b/core/http/src/uri/fmt/uri_display.rs index 469915bc..9be25518 100644 --- a/core/http/src/uri/fmt/uri_display.rs +++ b/core/http/src/uri/fmt/uri_display.rs @@ -259,12 +259,13 @@ use crate::uri::fmt::{Part, Path, Query, Formatter}; /// use rocket::response::Redirect; /// /// impl UriDisplay for Name<'_> { -/// // Delegates to the `UriDisplay` implementation for `str` via the call -/// // to `write_value` to ensure that the written string is URI-safe. In -/// // this case, the string will be percent encoded. Prefixes the inner -/// // name with `name:`. +/// // Writes the raw string `name:`, which is URI-safe, and then delegates +/// // to the `UriDisplay` implementation for `str` which ensures that +/// // string is written in a URI-safe manner. In this case, the string will +/// // be percent encoded. /// fn fmt(&self, f: &mut Formatter) -> fmt::Result { -/// f.write_value(&format!("name:{}", self.0)) +/// f.write_raw("name:")?; +/// UriDisplay::fmt(&self.0, f) /// } /// } /// @@ -408,6 +409,9 @@ impl, E> UriDisplay for Result { } } +#[cfg(feature = "uuid")] impl_with_display!(_uuid::Uuid); +#[cfg(feature = "uuid")] crate::impl_from_uri_param_identity!(_uuid::Uuid); + // And finally, the `Ignorable` trait, which has sugar of `_` in the `uri!` // macro, which expands to a typecheck. diff --git a/core/lib/Cargo.toml b/core/lib/Cargo.toml index d0eb76bd..db84dda8 100644 --- a/core/lib/Cargo.toml +++ b/core/lib/Cargo.toml @@ -24,11 +24,13 @@ tls = ["rocket_http/tls"] secrets = ["rocket_http/private-cookies"] json = ["serde_json", "tokio/io-util"] msgpack = ["rmp-serde", "tokio/io-util"] +uuid = ["_uuid", "rocket_http/uuid"] [dependencies] # Serialization dependencies. serde_json = { version = "1.0.26", optional = true } rmp-serde = { version = "0.15.0", optional = true } +_uuid = { package = "uuid", version = "0.8", optional = true, features = ["serde"] } # Non-optional, core dependencies from here on out. futures = "0.3.0" diff --git a/core/lib/src/lib.rs b/core/lib/src/lib.rs index aa2b3184..27a641e9 100644 --- a/core/lib/src/lib.rs +++ b/core/lib/src/lib.rs @@ -64,6 +64,7 @@ //! | `tls` | Support for [TLS] encrypted connections. | //! | `json` | Support for [JSON (de)serialization]. | //! | `msgpack` | Support for [MessagePack (de)serialization]. | +//! | `uuid` | Support for [UUID value parsing and (de)serialization]. | //! //! Features can be selectively enabled in `Cargo.toml`: //! @@ -74,6 +75,7 @@ //! //! [JSON (de)serialization]: crate::serde::json //! [MessagePack (de)serialization]: crate::serde::msgpack +//! [UUID value parsing and (de)serialization]: crate::serde::uuid //! [private cookies]: https://rocket.rs/master/guide/requests/#private-cookies //! [TLS]: https://rocket.rs/master/guide/configuration/#tls //! diff --git a/core/lib/src/serde/mod.rs b/core/lib/src/serde/mod.rs index 932bfbc8..598cc233 100644 --- a/core/lib/src/serde/mod.rs +++ b/core/lib/src/serde/mod.rs @@ -16,3 +16,7 @@ pub mod json; #[cfg(feature = "msgpack")] #[cfg_attr(nightly, doc(cfg(feature = "msgpack")))] pub mod msgpack; + +#[cfg(feature = "uuid")] +#[cfg_attr(nightly, doc(cfg(feature = "uuid")))] +pub mod uuid; diff --git a/core/lib/src/serde/uuid.rs b/core/lib/src/serde/uuid.rs new file mode 100644 index 00000000..7db4223e --- /dev/null +++ b/core/lib/src/serde/uuid.rs @@ -0,0 +1,141 @@ +//! UUID path/query parameter and form value parsing support. +//! +//! # Enabling +//! +//! This module is only available when the `uuid` feature is enabled. Enable it +//! in `Cargo.toml` as follows: +//! +//! ```toml +//! [dependencies.rocket] +//! version = "0.5.0-dev" +//! features = ["uuid"] +//! ``` +//! +//! # Usage +//! +//! `Uuid` implements [`FromParam`] and [`FromFormField`] (i.e, +//! [`FromForm`](crate::form::FromForm)), allowing UUID values to be accepted +//! directly in paths, queries, and forms. You can use the `Uuid` type directly +//! as a target of a dynamic parameter: +//! +//! ```rust +//! # #[macro_use] extern crate rocket; +//! use rocket::serde::uuid::Uuid; +//! +//! #[get("/users/")] +//! fn user(id: Uuid) -> String { +//! format!("We found: {}", id) +//! } +//! ``` +//! +//! You can also use the `Uuid` as a form value, including in query strings: +//! +//! ```rust +//! # #[macro_use] extern crate rocket; +//! use rocket::serde::uuid::Uuid; +//! +//! #[get("/user?")] +//! fn user(id: Uuid) -> String { +//! format!("User ID: {}", id) +//! } +//! ``` +//! +//! Additionally, `Uuid` implements `UriDisplay

` for all `P`. As such, route +//! URIs including `Uuid`s can be generated in a type-safe manner: +//! +//! ```rust +//! # #[macro_use] extern crate rocket; +//! use rocket::serde::uuid::Uuid; +//! use rocket::response::Redirect; +//! +//! #[get("/user/")] +//! fn user(id: Uuid) -> String { +//! format!("User ID: {}", id) +//! } +//! +//! #[get("/user?")] +//! fn old_user_path(id: Uuid) -> Redirect { +//! # let _ = Redirect::to(uri!(user(&id))); +//! # let _ = Redirect::to(uri!(old_user_path(id))); +//! # let _ = Redirect::to(uri!(old_user_path(&id))); +//! Redirect::to(uri!(user(id))) +//! } +//! ``` +//! +//! # Extra Features +//! +//! The [`uuid`](https://docs.rs/uuid/0.8) crate exposes extra `v{n}` features +//! for generating UUIDs which are not enabled by Rocket. To enable these +//! features, depend on `uuid` directly. The extra functionality can be accessed +//! via both `rocket::serde::uuid::Uuid` or the direct `uuid::Uuid`; the types +//! are one and the same. +//! +//! ```toml +//! [dependencies.uuid] +//! version = "0.8" +//! features = ["v1", "v4"] +//! ``` + +use crate::request::FromParam; +use crate::form::{self, FromFormField, ValueField}; + +/// A Universally Unique Identifier (UUID). +/// +/// # Examples +/// +/// To parse a UUID and print it as a urn: +/// +/// ```rust +/// use rocket::serde::uuid::{Uuid, Error}; +/// +/// # fn f() -> Result<(), Error> { +/// let uuid = Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8")?; +/// println!("{}", uuid.to_urn()); +/// # Ok(()) +/// # } +/// ``` +/// +pub use _uuid::Uuid; + +pub use _uuid::{Builder, Variant, Version}; + +/// Type alias for the error returned on [`FromParam`] or [`FromFormField`] +/// failure. +pub type Error = <_uuid::Uuid as std::str::FromStr>::Err; + +impl<'a> FromParam<'a> for Uuid { + type Error = Error; + + /// A value is successfully parsed if `param` is a properly formatted Uuid. + /// Otherwise, an error is returned. + #[inline(always)] + fn from_param(param: &'a str) -> Result { + param.parse() + } +} + +impl<'v> FromFormField<'v> for Uuid { + #[inline] + fn from_value(field: ValueField<'v>) -> form::Result<'v, Self> { + Ok(field.value.parse().map_err(form::error::Error::custom)?) + } +} + +#[cfg(test)] +mod test { + use super::{Uuid, FromParam}; + + #[test] + fn test_from_param() { + let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2"; + let uuid_wrapper = Uuid::from_param(uuid_str.into()).unwrap(); + assert_eq!(uuid_str, uuid_wrapper.to_string()) + } + + #[test] + #[should_panic(expected = "InvalidLength")] + fn test_from_param_invalid() { + let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2p"; + Uuid::from_param(uuid_str.into()).unwrap(); + } +} diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 318216c8..de5ec7df 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -15,7 +15,6 @@ members = [ "templating", "testing", "tls", - "uuid", "pastebin", "todo", diff --git a/examples/README.md b/examples/README.md index 990c527d..1ba45134 100644 --- a/examples/README.md +++ b/examples/README.md @@ -60,7 +60,7 @@ This directory contains projects showcasing Rocket's features. * **[`serialization`](./serialization)** - Showcases JSON and MessagePack (de)serialization support by implementing a CRUD-like message API in JSON - and a simply read/echo API in MessagePack. + and a simply read/echo API in MessagePack. Showcases UUID parsing support. * **[`state`](./state)** - Illustrates the use of request-local state and managed state. Uses request-local state to cache "expensive" per-request @@ -80,6 +80,3 @@ This directory contains projects showcasing Rocket's features. * **[`tls`](./tls)** - Illustrates configuring TLS with a variety of key pair kinds. - - * **[`uuid`](./uuid)** - Uses UUID support in `contrib`, converting between - `contrib::Uuid` type and the `uuid` crate `Uuid`. diff --git a/examples/serialization/Cargo.toml b/examples/serialization/Cargo.toml index a9be00d0..1175b332 100644 --- a/examples/serialization/Cargo.toml +++ b/examples/serialization/Cargo.toml @@ -7,4 +7,4 @@ publish = false [dependencies.rocket] path = "../../core/lib" -features = ["json", "msgpack"] +features = ["json", "msgpack", "uuid"] diff --git a/examples/serialization/src/main.rs b/examples/serialization/src/main.rs index ca054acb..07a7e499 100644 --- a/examples/serialization/src/main.rs +++ b/examples/serialization/src/main.rs @@ -4,10 +4,12 @@ mod json; mod msgpack; +mod uuid; #[launch] fn rocket() -> _ { rocket::build() .attach(json::stage()) .attach(msgpack::stage()) + .attach(uuid::stage()) } diff --git a/examples/serialization/src/tests.rs b/examples/serialization/src/tests.rs index 3039a6f4..1a7846ba 100644 --- a/examples/serialization/src/tests.rs +++ b/examples/serialization/src/tests.rs @@ -1,6 +1,6 @@ use rocket::local::blocking::Client; use rocket::http::{Status, ContentType, Accept}; -use rocket::serde::{Serialize, Deserialize}; +use rocket::serde::{Serialize, Deserialize, uuid::Uuid}; #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(crate = "rocket::serde")] @@ -114,3 +114,25 @@ fn msgpack_post() { assert_eq!(res.status(), Status::Ok); assert_eq!(res.into_string().unwrap(), "Goodbye, world!"); } + +#[test] +fn uuid() { + let client = Client::tracked(super::rocket()).unwrap(); + + let pairs = &[ + ("7f205202-7ba1-4c39-b2fc-3e630722bf9f", "We found: Lacy"), + ("4da34121-bc7d-4fc1-aee6-bf8de0795333", "We found: Bob"), + ("ad962969-4e3d-4de7-ac4a-2d86d6d10839", "We found: George"), + ("e18b3a5c-488f-4159-a240-2101e0da19fd", + "Missing person for UUID: e18b3a5c-488f-4159-a240-2101e0da19fd"), + ]; + + for (uuid, response) in pairs { + let uuid = Uuid::parse_str(uuid).unwrap(); + let res = client.get(uri!(super::uuid::people(uuid))).dispatch(); + assert_eq!(res.into_string().unwrap(), *response); + } + + let res = client.get("/people/not-a-uuid").dispatch(); + assert_eq!(res.status(), Status::NotFound); +} diff --git a/examples/serialization/src/uuid.rs b/examples/serialization/src/uuid.rs new file mode 100644 index 00000000..56225028 --- /dev/null +++ b/examples/serialization/src/uuid.rs @@ -0,0 +1,29 @@ +use std::collections::HashMap; + +use rocket::State; +use rocket::serde::uuid::Uuid; + +// A small people mapping in managed state for the sake of this example. In a +// real application this would be a database. +struct People(HashMap); + +#[get("/people/")] +fn people(id: Uuid, people: &State) -> Result { + Ok(people.0.get(&id) + .map(|person| format!("We found: {}", person)) + .ok_or_else(|| format!("Missing person for UUID: {}", id))?) +} + +pub fn stage() -> rocket::fairing::AdHoc { + // Seed the "database". + let mut map = HashMap::new(); + map.insert("7f205202-7ba1-4c39-b2fc-3e630722bf9f".parse().unwrap(), "Lacy"); + map.insert("4da34121-bc7d-4fc1-aee6-bf8de0795333".parse().unwrap(), "Bob"); + map.insert("ad962969-4e3d-4de7-ac4a-2d86d6d10839".parse().unwrap(), "George"); + + rocket::fairing::AdHoc::on_ignite("UUID", |rocket| async { + rocket + .manage(People(map)) + .mount("/", routes![people]) + }) +} diff --git a/examples/uuid/Cargo.toml b/examples/uuid/Cargo.toml deleted file mode 100644 index 1415e6f3..00000000 --- a/examples/uuid/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "uuid" -version = "0.1.0" -workspace = "../" -edition = "2018" -publish = false - -[dependencies] -rocket = { path = "../../core/lib" } - -[dependencies.rocket_contrib] -default-features = false -path = "../../contrib/lib" -features = ["uuid"] diff --git a/examples/uuid/src/main.rs b/examples/uuid/src/main.rs deleted file mode 100644 index b999805b..00000000 --- a/examples/uuid/src/main.rs +++ /dev/null @@ -1,36 +0,0 @@ -#[macro_use] extern crate rocket; - -use std::collections::HashMap; - -use rocket::State; -use rocket_contrib::uuid::Uuid; -use rocket_contrib::uuid::extern_uuid; - -#[cfg(test)] mod tests; - -// A small people mapping in managed state for the sake of this example. In a -// real application this would be a database. Notice that we use the external -// Uuid type here and not the rocket_contrib::uuid::Uuid type. We do this purely -// for demonstrative purposes; in practice, we could use the contrib `Uuid`. -struct People(HashMap); - -#[get("/people/")] -fn people(id: Uuid, people: &State) -> Result { - // Because Uuid implements the Deref trait, we use Deref coercion to convert - // rocket_contrib::uuid::Uuid to uuid::Uuid. - Ok(people.0.get(&id) - .map(|person| format!("We found: {}", person)) - .ok_or_else(|| format!("Person not found for UUID: {}", id))?) -} - -#[launch] -fn rocket() -> _ { - let mut map = HashMap::new(); - map.insert("7f205202-7ba1-4c39-b2fc-3e630722bf9f".parse().unwrap(), "Lacy"); - map.insert("4da34121-bc7d-4fc1-aee6-bf8de0795333".parse().unwrap(), "Bob"); - map.insert("ad962969-4e3d-4de7-ac4a-2d86d6d10839".parse().unwrap(), "George"); - - rocket::build() - .manage(People(map)) - .mount("/", routes![people]) -} diff --git a/examples/uuid/src/tests.rs b/examples/uuid/src/tests.rs deleted file mode 100644 index 4ba39c64..00000000 --- a/examples/uuid/src/tests.rs +++ /dev/null @@ -1,25 +0,0 @@ -use super::rocket; -use rocket::local::blocking::Client; -use rocket::http::Status; - -fn test(uri: &str, expected: &str) { - let client = Client::tracked(rocket()).unwrap(); - let res = client.get(uri).dispatch(); - assert_eq!(res.into_string(), Some(expected.into())); -} - -fn test_404(uri: &str) { - let client = Client::tracked(rocket()).unwrap(); - let res = client.get(uri).dispatch(); - assert_eq!(res.status(), Status::NotFound); -} - -#[test] -fn test_people() { - test("/people/7f205202-7ba1-4c39-b2fc-3e630722bf9f", "We found: Lacy"); - test("/people/4da34121-bc7d-4fc1-aee6-bf8de0795333", "We found: Bob"); - test("/people/ad962969-4e3d-4de7-ac4a-2d86d6d10839", "We found: George"); - test("/people/e18b3a5c-488f-4159-a240-2101e0da19fd", - "Person not found for UUID: e18b3a5c-488f-4159-a240-2101e0da19fd"); - test_404("/people/invalid_uuid"); -} diff --git a/scripts/test.sh b/scripts/test.sh index 1f0172a8..daac724f 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -89,6 +89,7 @@ function test_core() { tls json msgpack + uuid ) pushd "${CORE_LIB_ROOT}" > /dev/null 2>&1