1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
//! 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.4.11"
//! default-features = false
//! features = ["uuid"]
//! ```
pub extern crate uuid as uuid_crate;
use std::fmt;
use std::str::FromStr;
use std::ops::Deref;
use rocket::request::{FromParam, FromFormValue};
use rocket::http::RawStr;
pub use self::uuid_crate::parser::ParseError;
/// Implements [`FromParam`] and [`FromFormValue`] for accepting UUID values.
///
/// # Usage
///
/// To use, add the `uuid` feature to the `rocket_contrib` dependencies section
/// of your `Cargo.toml`:
///
/// ```toml
/// [dependencies.rocket_contrib]
/// version = "0.4.11"
/// default-features = false
/// features = ["uuid"]
/// ```
///
/// You can use the `Uuid` type directly as a target of a dynamic parameter:
///
/// ```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)
/// }
/// ```
///
/// You can also use the `Uuid` as a form value, including in query strings:
///
/// ```rust
/// # #![feature(proc_macro_hygiene, decl_macro)]
/// # #[macro_use] extern crate rocket;
/// # #[macro_use] extern crate rocket_contrib;
/// use rocket_contrib::uuid::Uuid;
///
/// #[get("/user?<id>")]
/// fn user(id: Uuid) -> String {
/// format!("User ID: {}", id)
/// }
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct Uuid(uuid_crate::Uuid);
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::{uuid_crate, Uuid};
///
/// let uuid_str = "c1aa1e3b-9614-4895-9ebd-705255fa5bc2";
/// 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_crate::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 = ParseError;
/// A value is successfully parsed if `param` is a properly formatted Uuid.
/// Otherwise, a `ParseError` is returned.
#[inline(always)]
fn from_param(param: &'a RawStr) -> Result<Uuid, Self::Error> {
param.parse()
}
}
impl<'v> FromFormValue<'v> for Uuid {
type Error = &'v RawStr;
/// A value is successfully parsed if `form_value` is a properly formatted
/// Uuid. Otherwise, the raw form value is returned.
#[inline(always)]
fn from_form_value(form_value: &'v RawStr) -> Result<Uuid, &'v RawStr> {
form_value.parse().map_err(|_| form_value)
}
}
impl FromStr for Uuid {
type Err = ParseError;
#[inline]
fn from_str(s: &str) -> Result<Uuid, Self::Err> {
s.parse().map(Uuid)
}
}
impl Deref for Uuid {
type Target = uuid_crate::Uuid;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl PartialEq<uuid_crate::Uuid> for Uuid {
#[inline(always)]
fn eq(&self, other: &uuid_crate::Uuid) -> bool {
self.0.eq(other)
}
}
#[cfg(test)]
mod test {
use super::uuid_crate;
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_crate::Uuid = uuid_str.parse().unwrap();
let inner_uuid: uuid_crate::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_crate::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();
}
}