2018-10-13 01:52:38 +00:00
|
|
|
//! UUID parameter and form value parsing support.
|
2018-12-07 17:07:27 +00:00
|
|
|
//!
|
|
|
|
//! See the [`Uuid`](uuid::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]
|
2019-05-13 23:18:48 +00:00
|
|
|
//! version = "0.5.0-dev"
|
2018-12-07 17:07:27 +00:00
|
|
|
//! default-features = false
|
|
|
|
//! features = ["uuid"]
|
|
|
|
//! ```
|
2018-10-13 01:52:38 +00:00
|
|
|
|
2018-10-07 00:24:11 +00:00
|
|
|
pub extern crate uuid as uuid_crate;
|
2017-01-10 21:33:30 +00:00
|
|
|
|
|
|
|
use std::fmt;
|
|
|
|
use std::str::FromStr;
|
|
|
|
use std::ops::Deref;
|
2017-01-14 16:20:15 +00:00
|
|
|
|
2017-02-04 01:09:22 +00:00
|
|
|
use rocket::request::{FromParam, FromFormValue};
|
2017-03-31 06:06:53 +00:00
|
|
|
use rocket::http::RawStr;
|
2017-01-10 21:33:30 +00:00
|
|
|
|
2018-10-07 00:24:11 +00:00
|
|
|
pub use self::uuid_crate::parser::ParseError;
|
2017-01-10 21:33:30 +00:00
|
|
|
|
2018-10-13 01:52:38 +00:00
|
|
|
/// Implements [`FromParam`] and [`FromFormValue`] for accepting UUID values.
|
2017-01-10 21:33:30 +00:00
|
|
|
///
|
|
|
|
/// # Usage
|
|
|
|
///
|
|
|
|
/// To use, add the `uuid` feature to the `rocket_contrib` dependencies section
|
|
|
|
/// of your `Cargo.toml`:
|
|
|
|
///
|
|
|
|
/// ```toml
|
|
|
|
/// [dependencies.rocket_contrib]
|
2019-05-13 23:18:48 +00:00
|
|
|
/// version = "0.5.0-dev"
|
2017-01-10 21:33:30 +00:00
|
|
|
/// default-features = false
|
|
|
|
/// features = ["uuid"]
|
|
|
|
/// ```
|
|
|
|
///
|
2018-04-14 01:39:34 +00:00
|
|
|
/// You can use the `Uuid` type directly as a target of a dynamic parameter:
|
2017-01-10 21:33:30 +00:00
|
|
|
///
|
2018-10-07 00:24:11 +00:00
|
|
|
/// ```rust
|
2019-06-20 06:03:21 +00:00
|
|
|
/// # #![feature(proc_macro_hygiene)]
|
2018-10-07 00:24:11 +00:00
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// # #[macro_use] extern crate rocket_contrib;
|
|
|
|
/// use rocket_contrib::uuid::Uuid;
|
|
|
|
///
|
2017-01-10 21:33:30 +00:00
|
|
|
/// #[get("/users/<id>")]
|
2018-04-14 01:39:34 +00:00
|
|
|
/// fn user(id: Uuid) -> String {
|
2017-01-10 21:33:30 +00:00
|
|
|
/// format!("We found: {}", id)
|
|
|
|
/// }
|
|
|
|
/// ```
|
2017-02-04 01:09:22 +00:00
|
|
|
///
|
2018-04-14 01:39:34 +00:00
|
|
|
/// You can also use the `Uuid` as a form value, including in query strings:
|
2017-02-04 01:09:22 +00:00
|
|
|
///
|
2018-10-07 00:24:11 +00:00
|
|
|
/// ```rust
|
2019-06-20 06:03:21 +00:00
|
|
|
/// # #![feature(proc_macro_hygiene)]
|
2018-10-07 00:24:11 +00:00
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// # #[macro_use] extern crate rocket_contrib;
|
|
|
|
/// use rocket_contrib::uuid::Uuid;
|
2017-02-04 01:09:22 +00:00
|
|
|
///
|
2018-10-07 00:24:11 +00:00
|
|
|
/// #[get("/user?<id>")]
|
|
|
|
/// fn user(id: Uuid) -> String {
|
|
|
|
/// format!("User ID: {}", id)
|
2017-02-04 01:09:22 +00:00
|
|
|
/// }
|
2017-01-10 21:33:30 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
2018-10-07 00:24:11 +00:00
|
|
|
pub struct Uuid(uuid_crate::Uuid);
|
2017-01-10 21:33:30 +00:00
|
|
|
|
2018-04-14 01:39:34 +00:00
|
|
|
impl Uuid {
|
2018-07-12 03:44:09 +00:00
|
|
|
/// Consumes the Uuid wrapper, returning the underlying `Uuid` type.
|
2017-01-10 21:33:30 +00:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
/// ```rust
|
|
|
|
/// # extern crate rocket_contrib;
|
|
|
|
/// # use std::str::FromStr;
|
|
|
|
/// # fn main() {
|
2018-10-07 00:24:11 +00:00
|
|
|
/// use rocket_contrib::uuid::{uuid_crate, Uuid};
|
|
|
|
///
|
2017-01-10 21:33:30 +00:00
|
|
|
/// let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2";
|
2018-10-07 00:24:11 +00:00
|
|
|
/// 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();
|
|
|
|
///
|
2017-01-10 21:33:30 +00:00
|
|
|
/// assert_eq!(real_uuid, my_inner_uuid);
|
|
|
|
/// # }
|
|
|
|
/// ```
|
|
|
|
#[inline(always)]
|
2018-10-07 00:24:11 +00:00
|
|
|
pub fn into_inner(self) -> uuid_crate::Uuid {
|
2017-01-10 21:33:30 +00:00
|
|
|
self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-14 01:39:34 +00:00
|
|
|
impl fmt::Display for Uuid {
|
2017-01-14 16:20:15 +00:00
|
|
|
#[inline(always)]
|
2019-06-13 02:17:59 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2017-01-10 21:33:30 +00:00
|
|
|
self.0.fmt(f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-14 01:39:34 +00:00
|
|
|
impl<'a> FromParam<'a> for Uuid {
|
2018-10-07 00:24:11 +00:00
|
|
|
type Error = ParseError;
|
2017-01-10 21:33:30 +00:00
|
|
|
|
2018-04-14 01:39:34 +00:00
|
|
|
/// A value is successfully parsed if `param` is a properly formatted Uuid.
|
2018-10-07 00:24:11 +00:00
|
|
|
/// Otherwise, a `ParseError` is returned.
|
2017-01-14 16:20:15 +00:00
|
|
|
#[inline(always)]
|
2018-04-14 01:39:34 +00:00
|
|
|
fn from_param(param: &'a RawStr) -> Result<Uuid, Self::Error> {
|
2017-02-04 01:09:22 +00:00
|
|
|
param.parse()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-14 01:39:34 +00:00
|
|
|
impl<'v> FromFormValue<'v> for Uuid {
|
2017-03-31 06:06:53 +00:00
|
|
|
type Error = &'v RawStr;
|
2017-02-04 01:09:22 +00:00
|
|
|
|
|
|
|
/// A value is successfully parsed if `form_value` is a properly formatted
|
2018-04-14 01:39:34 +00:00
|
|
|
/// Uuid. Otherwise, the raw form value is returned.
|
2017-03-31 06:06:53 +00:00
|
|
|
#[inline(always)]
|
2018-04-14 01:39:34 +00:00
|
|
|
fn from_form_value(form_value: &'v RawStr) -> Result<Uuid, &'v RawStr> {
|
2017-02-04 01:09:22 +00:00
|
|
|
form_value.parse().map_err(|_| form_value)
|
2017-01-10 21:33:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-14 01:39:34 +00:00
|
|
|
impl FromStr for Uuid {
|
2018-10-07 00:24:11 +00:00
|
|
|
type Err = ParseError;
|
2017-01-10 21:33:30 +00:00
|
|
|
|
2017-01-14 16:20:15 +00:00
|
|
|
#[inline]
|
2018-04-14 01:39:34 +00:00
|
|
|
fn from_str(s: &str) -> Result<Uuid, Self::Err> {
|
2019-06-13 02:17:59 +00:00
|
|
|
s.parse().map(Uuid)
|
2017-01-10 21:33:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-14 01:39:34 +00:00
|
|
|
impl Deref for Uuid {
|
2018-10-07 00:24:11 +00:00
|
|
|
type Target = uuid_crate::Uuid;
|
2017-01-10 21:33:30 +00:00
|
|
|
|
2018-07-28 16:58:10 +00:00
|
|
|
fn deref(&self) -> &Self::Target {
|
2017-01-10 21:33:30 +00:00
|
|
|
&self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-07 00:24:11 +00:00
|
|
|
impl PartialEq<uuid_crate::Uuid> for Uuid {
|
2017-01-14 16:20:15 +00:00
|
|
|
#[inline(always)]
|
2018-10-07 00:24:11 +00:00
|
|
|
fn eq(&self, other: &uuid_crate::Uuid) -> bool {
|
2017-01-10 21:33:30 +00:00
|
|
|
self.0.eq(other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
2018-10-07 00:24:11 +00:00
|
|
|
use super::uuid_crate;
|
2018-09-09 20:20:11 +00:00
|
|
|
use super::Uuid;
|
2017-01-10 21:33:30 +00:00
|
|
|
use super::FromParam;
|
|
|
|
use super::FromStr;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from_str() {
|
|
|
|
let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2";
|
2018-04-14 01:39:34 +00:00
|
|
|
let uuid_wrapper = Uuid::from_str(uuid_str).unwrap();
|
2017-01-10 21:33:30 +00:00
|
|
|
assert_eq!(uuid_str, uuid_wrapper.to_string())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from_param() {
|
|
|
|
let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2";
|
2018-04-14 01:39:34 +00:00
|
|
|
let uuid_wrapper = Uuid::from_param(uuid_str.into()).unwrap();
|
2017-01-10 21:33:30 +00:00
|
|
|
assert_eq!(uuid_str, uuid_wrapper.to_string())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_into_inner() {
|
|
|
|
let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2";
|
2018-04-14 01:39:34 +00:00
|
|
|
let uuid_wrapper = Uuid::from_param(uuid_str.into()).unwrap();
|
2018-10-07 00:24:11 +00:00
|
|
|
let real_uuid: uuid_crate::Uuid = uuid_str.parse().unwrap();
|
|
|
|
let inner_uuid: uuid_crate::Uuid = uuid_wrapper.into_inner();
|
2017-01-10 21:33:30 +00:00
|
|
|
assert_eq!(real_uuid, inner_uuid)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_partial_eq() {
|
|
|
|
let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2";
|
2018-04-14 01:39:34 +00:00
|
|
|
let uuid_wrapper = Uuid::from_param(uuid_str.into()).unwrap();
|
2018-10-07 00:24:11 +00:00
|
|
|
let real_uuid: uuid_crate::Uuid = uuid_str.parse().unwrap();
|
2017-01-10 21:33:30 +00:00
|
|
|
assert_eq!(uuid_wrapper, real_uuid)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2018-09-09 20:20:11 +00:00
|
|
|
#[should_panic(expected = "InvalidLength")]
|
2017-01-10 21:33:30 +00:00
|
|
|
fn test_from_param_invalid() {
|
|
|
|
let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2p";
|
2018-09-09 20:20:11 +00:00
|
|
|
Uuid::from_param(uuid_str.into()).unwrap();
|
2017-01-10 21:33:30 +00:00
|
|
|
}
|
|
|
|
}
|