finchers_session/
session.rs

1use finchers::endpoint;
2use finchers::error::Error;
3use finchers::input::Input;
4
5use futures::{Future, IntoFuture, Poll};
6
7/// The trait representing the backend to manage session value.
8#[allow(missing_docs)]
9pub trait RawSession {
10    type WriteFuture: Future<Item = (), Error = Error>;
11
12    fn get(&self) -> Option<&str>;
13    fn set(&mut self, value: String);
14    fn remove(&mut self);
15    fn write(self, input: &mut Input) -> Self::WriteFuture;
16}
17
18/// A struct which manages the session value per request.
19#[derive(Debug)]
20#[must_use = "The value must be convert into a Future to finish the session handling."]
21pub struct Session<S: RawSession> {
22    raw: S,
23}
24
25impl<S> Session<S>
26where
27    S: RawSession,
28{
29    #[allow(missing_docs)]
30    pub fn new(raw: S) -> Session<S> {
31        Session { raw }
32    }
33
34    /// Get the session value if available.
35    pub fn get(&self) -> Option<&str> {
36        self.raw.get()
37    }
38
39    /// Set the session value.
40    pub fn set(&mut self, value: impl Into<String>) {
41        self.raw.set(value.into());
42    }
43
44    /// Annotates to remove session value to the backend.
45    pub fn remove(&mut self) {
46        self.raw.remove();
47    }
48
49    #[allow(missing_docs)]
50    pub fn with<R>(
51        mut self,
52        f: impl FnOnce(&mut Self) -> R,
53    ) -> impl Future<Item = R::Item, Error = Error>
54    where
55        R: IntoFuture<Error = Error>,
56    {
57        f(&mut self)
58            .into_future()
59            .and_then(move |item| self.into_future().map(move |()| item))
60    }
61}
62
63impl<S> IntoFuture for Session<S>
64where
65    S: RawSession,
66{
67    type Item = ();
68    type Error = Error;
69    type Future = WriteSessionFuture<S::WriteFuture>;
70
71    fn into_future(self) -> Self::Future {
72        WriteSessionFuture {
73            future: endpoint::with_get_cx(|input| self.raw.write(input)),
74        }
75    }
76}
77
78#[derive(Debug)]
79#[must_use = "futures do not anything unless polled."]
80pub struct WriteSessionFuture<F> {
81    future: F,
82}
83
84impl<F> Future for WriteSessionFuture<F>
85where
86    F: Future<Item = ()>,
87    F::Error: Into<Error>,
88{
89    type Item = ();
90    type Error = Error;
91
92    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
93        self.future.poll().map_err(Into::into)
94    }
95}