commit 983ee9b32d1d5efc15388c2a2feac7ec9d274285
parent b4f85daaf248e989f22a78a3ec787759674df9d2
Author: Sergio Benitez <sb@sergio.bz>
Date: Sat, 3 Nov 2018 01:51:00 -0700
Make inner 'LenientForm' field public. Add 'State::from()'.
Diffstat:
3 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/core/lib/src/request/form/lenient.rs b/core/lib/src/request/form/lenient.rs
@@ -59,7 +59,7 @@ use http::uri::FromUriParam;
/// forms = 524288
/// ```
#[derive(Debug)]
-pub struct LenientForm<T>(crate T);
+pub struct LenientForm<T>(pub T);
impl<T> LenientForm<T> {
/// Consumes `self` and returns the parsed value.
diff --git a/core/lib/src/request/state.rs b/core/lib/src/request/state.rs
@@ -1,5 +1,6 @@
use std::ops::Deref;
+use Rocket;
use request::{self, FromRequest, Request};
use outcome::Outcome;
use http::Status;
@@ -78,6 +79,29 @@ use http::Status;
/// }
/// }
/// ```
+///
+/// # Testing with `State`
+///
+/// When unit testing your application, you may find it necessary to manually
+/// construct a type of `State` to pass to your functions. To do so, use the
+/// [`State::from()`] static method:
+///
+/// ```rust
+/// # #![feature(proc_macro_hygiene, decl_macro)]
+/// # #[macro_use] extern crate rocket;
+/// use rocket::State;
+///
+/// struct MyManagedState(usize);
+///
+/// #[get("/")]
+/// fn handler(state: State<MyManagedState>) -> String {
+/// state.0.to_string()
+/// }
+///
+/// let rocket = rocket::ignite().manage(MyManagedState(127));
+/// let state = State::from(&rocket).expect("managing `MyManagedState`");
+/// assert_eq!(handler(state), "127");
+/// ```
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct State<'r, T: Send + Sync + 'static>(&'r T);
@@ -112,6 +136,33 @@ impl<'r, T: Send + Sync + 'static> State<'r, T> {
pub fn inner(&self) -> &'r T {
self.0
}
+
+ /// Returns the managed state value in `rocket` for the type `T` if it is
+ /// being managed by `rocket`. Otherwise, returns `None`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use rocket::State;
+ ///
+ /// #[derive(Debug, PartialEq)]
+ /// struct Managed(usize);
+ ///
+ /// #[derive(Debug, PartialEq)]
+ /// struct Unmanaged(usize);
+ ///
+ /// let rocket = rocket::ignite().manage(Managed(7));
+ ///
+ /// let state: Option<State<Managed>> = State::from(&rocket);
+ /// assert_eq!(state.map(|s| s.inner()), Some(&Managed(7)));
+ ///
+ /// let state: Option<State<Unmanaged>> = State::from(&rocket);
+ /// assert_eq!(state, None);
+ /// ```
+ #[inline(always)]
+ pub fn from(rocket: &'r Rocket) -> Option<Self> {
+ rocket.state.try_get::<T>().map(State)
+ }
}
impl<'a, 'r, T: Send + Sync + 'static> FromRequest<'a, 'r> for State<'r, T> {
diff --git a/examples/state/src/tests.rs b/examples/state/src/tests.rs
@@ -25,6 +25,18 @@ fn test_count() {
assert_eq!(get_count(&client), 100);
}
+#[test]
+fn test_raw_state_count() {
+ use rocket::State;
+ use super::{count, index};
+
+ let rocket = super::rocket();
+
+ assert_eq!(count(State::from(&rocket).unwrap()), "0");
+ assert!(index(State::from(&rocket).unwrap()).0.contains("Visits: 1"));
+ assert_eq!(count(State::from(&rocket).unwrap()), "1");
+}
+
// Cargo runs each test in parallel on different threads. We use all of these
// tests below to show (and assert) that state is managed per-Rocket instance.
#[test] fn test_count_parallel() { test_count() }