1#![cfg_attr(test, deny(warnings))]
2#![deny(missing_docs)]
3
4extern crate iron;
8extern crate plugin;
9
10use iron::{Request, Response, BeforeMiddleware, AfterMiddleware, IronResult};
11use iron::typemap::Key;
12use std::sync::{Arc, RwLock, Mutex};
13use std::fmt;
14use std::error::Error;
15use plugin::Plugin;
16
17#[derive(Clone, Debug)]
19pub enum PersistentError {
20 NotFound
22}
23
24impl Error for PersistentError {
25 fn description(&self) -> &str {
26 match *self {
27 PersistentError::NotFound => "Value not found in extensions."
28 }
29 }
30}
31
32impl fmt::Display for PersistentError {
33 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
34 self.description().fmt(f)
35 }
36}
37
38pub trait PersistentInto<T> {
45 fn persistent_into(self) -> T;
47}
48
49impl<T> PersistentInto<T> for T {
50 fn persistent_into(self) -> T { self }
51}
52
53impl<T> PersistentInto<Arc<T>> for T {
54 fn persistent_into(self) -> Arc<T> {
55 Arc::new(self)
56 }
57}
58
59impl<T> PersistentInto<Arc<Mutex<T>>> for T {
60 fn persistent_into(self) -> Arc<Mutex<T>> {
61 Arc::new(Mutex::new(self))
62 }
63}
64
65impl<T> PersistentInto<Arc<RwLock<T>>> for T {
66 fn persistent_into(self) -> Arc<RwLock<T>> {
67 Arc::new(RwLock::new(self))
68 }
69}
70
71pub struct State<P: Key> {
87 data: Arc<RwLock<P::Value>>
88}
89
90pub struct Read<P: Key> {
102 data: Arc<P::Value>
103}
104
105pub struct Write<P: Key> {
119 data: Arc<Mutex<P::Value>>
120}
121
122impl<P: Key> Clone for Read<P> where P::Value: Send + Sync {
123 fn clone(&self) -> Read<P> {
124 Read { data: self.data.clone() }
125 }
126}
127
128impl<P: Key> Clone for State<P> where P::Value: Send + Sync {
129 fn clone(&self) -> State<P> {
130 State { data: self.data.clone() }
131 }
132}
133
134impl<P: Key> Clone for Write<P> where P::Value: Send {
135 fn clone(&self) -> Write<P> {
136 Write { data: self.data.clone() }
137 }
138}
139
140impl<P: Key> Key for State<P> where P::Value: 'static {
141 type Value = Arc<RwLock<P::Value>>;
142}
143
144impl<P: Key> Key for Read<P> where P::Value: 'static {
145 type Value = Arc<P::Value>;
146}
147
148impl<P: Key> Key for Write<P> where P::Value: 'static {
149 type Value = Arc<Mutex<P::Value>>;
150}
151
152impl<'a, 'b, P: Key> Plugin<Request<'a, 'b>> for State<P> where P::Value: Send + Sync {
153 type Error = PersistentError;
154 fn eval(req: &mut Request<'a, 'b>) -> Result<Arc<RwLock<P::Value>>, PersistentError> {
155 req.extensions.get::<State<P>>().cloned().ok_or(PersistentError::NotFound)
156 }
157}
158
159impl<'a, 'b, P: Key> Plugin<Request<'a, 'b>> for Read<P> where P::Value: Send + Sync {
160 type Error = PersistentError;
161 fn eval(req: &mut Request<'a, 'b>) -> Result<Arc<P::Value>, PersistentError> {
162 req.extensions.get::<Read<P>>().cloned().ok_or(PersistentError::NotFound)
163 }
164}
165
166impl<'a, 'b, P: Key> Plugin<Request<'a, 'b>> for Write<P> where P::Value: Send {
167 type Error = PersistentError;
168 fn eval(req: &mut Request<'a, 'b>) -> Result<Arc<Mutex<P::Value>>, PersistentError> {
169 req.extensions.get::<Write<P>>().cloned().ok_or(PersistentError::NotFound)
170 }
171}
172
173impl<P: Key> BeforeMiddleware for State<P> where P::Value: Send + Sync {
174 fn before(&self, req: &mut Request) -> IronResult<()> {
175 req.extensions.insert::<State<P>>(self.data.clone());
176 Ok(())
177 }
178}
179
180impl<P: Key> BeforeMiddleware for Read<P> where P::Value: Send + Sync {
181 fn before(&self, req: &mut Request) -> IronResult<()> {
182 req.extensions.insert::<Read<P>>(self.data.clone());
183 Ok(())
184 }
185}
186
187impl<P: Key> BeforeMiddleware for Write<P> where P::Value: Send {
188 fn before(&self, req: &mut Request) -> IronResult<()> {
189 req.extensions.insert::<Write<P>>(self.data.clone());
190 Ok(())
191 }
192}
193
194impl<P: Key> AfterMiddleware for State<P> where P::Value: Send + Sync {
195 fn after(&self, _: &mut Request, mut res: Response) -> IronResult<Response> {
196 res.extensions.insert::<State<P>>(self.data.clone());
197 Ok(res)
198 }
199}
200
201impl<P: Key> AfterMiddleware for Read<P> where P::Value: Send + Sync {
202 fn after(&self, _: &mut Request, mut res: Response) -> IronResult<Response> {
203 res.extensions.insert::<Read<P>>(self.data.clone());
204 Ok(res)
205 }
206}
207
208impl<P: Key> AfterMiddleware for Write<P> where P::Value: Send {
209 fn after(&self, _: &mut Request, mut res: Response) -> IronResult<Response> {
210 res.extensions.insert::<Write<P>>(self.data.clone());
211 Ok(res)
212 }
213}
214
215impl<P: Key> State<P> where P::Value: Send + Sync {
216 pub fn both<T>(start: T) -> (State<P>, State<P>) where T: PersistentInto<Arc<RwLock<P::Value>>> {
220 let x = State { data: start.persistent_into() };
221 (x.clone(), x)
222 }
223
224 pub fn one<T>(start: T) -> State<P> where T: PersistentInto<Arc<RwLock<P::Value>>> {
229 State { data: start.persistent_into() }
230 }
231}
232
233impl<P: Key> Read<P> where P::Value: Send + Sync {
234 pub fn both<T>(start: T) -> (Read<P>, Read<P>) where T: PersistentInto<Arc<P::Value>> {
238 let x = Read { data: start.persistent_into() };
239 (x.clone(), x)
240 }
241
242 pub fn one<T>(start: T) -> Read<P> where T: PersistentInto<Arc<P::Value>> {
247 Read { data: start.persistent_into() }
248 }
249}
250
251impl<P: Key> Write<P> where P::Value: Send {
252 pub fn both<T>(start: T) -> (Write<P>, Write<P>) where T: PersistentInto<Arc<Mutex<P::Value>>> {
256 let x = Write { data: start.persistent_into() };
257 (x.clone(), x)
258 }
259
260 pub fn one<T>(start: T) -> Write<P> where T: PersistentInto<Arc<Mutex<P::Value>>> {
265 Write { data: start.persistent_into() }
266 }
267}