#![cfg_attr(test, deny(warnings))]
#![deny(missing_docs)]
extern crate iron;
extern crate plugin;
use iron::{Request, Response, BeforeMiddleware, AfterMiddleware, IronResult};
use iron::typemap::Key;
use std::sync::{Arc, RwLock, Mutex};
use std::fmt;
use std::error::Error;
use plugin::Plugin;
#[derive(Clone, Debug)]
pub enum PersistentError {
NotFound
}
impl Error for PersistentError {
fn description(&self) -> &str {
match *self {
PersistentError::NotFound => "Value not found in extensions."
}
}
}
impl fmt::Display for PersistentError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.description().fmt(f)
}
}
pub trait PersistentInto<T> {
fn persistent_into(self) -> T;
}
impl<T> PersistentInto<T> for T {
fn persistent_into(self) -> T { self }
}
impl<T> PersistentInto<Arc<T>> for T {
fn persistent_into(self) -> Arc<T> {
Arc::new(self)
}
}
impl<T> PersistentInto<Arc<Mutex<T>>> for T {
fn persistent_into(self) -> Arc<Mutex<T>> {
Arc::new(Mutex::new(self))
}
}
impl<T> PersistentInto<Arc<RwLock<T>>> for T {
fn persistent_into(self) -> Arc<RwLock<T>> {
Arc::new(RwLock::new(self))
}
}
pub struct State<P: Key> {
data: Arc<RwLock<P::Value>>
}
pub struct Read<P: Key> {
data: Arc<P::Value>
}
pub struct Write<P: Key> {
data: Arc<Mutex<P::Value>>
}
impl<P: Key> Clone for Read<P> where P::Value: Send + Sync {
fn clone(&self) -> Read<P> {
Read { data: self.data.clone() }
}
}
impl<P: Key> Clone for State<P> where P::Value: Send + Sync {
fn clone(&self) -> State<P> {
State { data: self.data.clone() }
}
}
impl<P: Key> Clone for Write<P> where P::Value: Send {
fn clone(&self) -> Write<P> {
Write { data: self.data.clone() }
}
}
impl<P: Key> Key for State<P> where P::Value: 'static {
type Value = Arc<RwLock<P::Value>>;
}
impl<P: Key> Key for Read<P> where P::Value: 'static {
type Value = Arc<P::Value>;
}
impl<P: Key> Key for Write<P> where P::Value: 'static {
type Value = Arc<Mutex<P::Value>>;
}
impl<'a, 'b, P: Key> Plugin<Request<'a, 'b>> for State<P> where P::Value: Send + Sync {
type Error = PersistentError;
fn eval(req: &mut Request<'a, 'b>) -> Result<Arc<RwLock<P::Value>>, PersistentError> {
req.extensions.get::<State<P>>().cloned().ok_or(PersistentError::NotFound)
}
}
impl<'a, 'b, P: Key> Plugin<Request<'a, 'b>> for Read<P> where P::Value: Send + Sync {
type Error = PersistentError;
fn eval(req: &mut Request<'a, 'b>) -> Result<Arc<P::Value>, PersistentError> {
req.extensions.get::<Read<P>>().cloned().ok_or(PersistentError::NotFound)
}
}
impl<'a, 'b, P: Key> Plugin<Request<'a, 'b>> for Write<P> where P::Value: Send {
type Error = PersistentError;
fn eval(req: &mut Request<'a, 'b>) -> Result<Arc<Mutex<P::Value>>, PersistentError> {
req.extensions.get::<Write<P>>().cloned().ok_or(PersistentError::NotFound)
}
}
impl<P: Key> BeforeMiddleware for State<P> where P::Value: Send + Sync {
fn before(&self, req: &mut Request) -> IronResult<()> {
req.extensions.insert::<State<P>>(self.data.clone());
Ok(())
}
}
impl<P: Key> BeforeMiddleware for Read<P> where P::Value: Send + Sync {
fn before(&self, req: &mut Request) -> IronResult<()> {
req.extensions.insert::<Read<P>>(self.data.clone());
Ok(())
}
}
impl<P: Key> BeforeMiddleware for Write<P> where P::Value: Send {
fn before(&self, req: &mut Request) -> IronResult<()> {
req.extensions.insert::<Write<P>>(self.data.clone());
Ok(())
}
}
impl<P: Key> AfterMiddleware for State<P> where P::Value: Send + Sync {
fn after(&self, _: &mut Request, mut res: Response) -> IronResult<Response> {
res.extensions.insert::<State<P>>(self.data.clone());
Ok(res)
}
}
impl<P: Key> AfterMiddleware for Read<P> where P::Value: Send + Sync {
fn after(&self, _: &mut Request, mut res: Response) -> IronResult<Response> {
res.extensions.insert::<Read<P>>(self.data.clone());
Ok(res)
}
}
impl<P: Key> AfterMiddleware for Write<P> where P::Value: Send {
fn after(&self, _: &mut Request, mut res: Response) -> IronResult<Response> {
res.extensions.insert::<Write<P>>(self.data.clone());
Ok(res)
}
}
impl<P: Key> State<P> where P::Value: Send + Sync {
pub fn both<T>(start: T) -> (State<P>, State<P>) where T: PersistentInto<Arc<RwLock<P::Value>>> {
let x = State { data: start.persistent_into() };
(x.clone(), x)
}
pub fn one<T>(start: T) -> State<P> where T: PersistentInto<Arc<RwLock<P::Value>>> {
State { data: start.persistent_into() }
}
}
impl<P: Key> Read<P> where P::Value: Send + Sync {
pub fn both<T>(start: T) -> (Read<P>, Read<P>) where T: PersistentInto<Arc<P::Value>> {
let x = Read { data: start.persistent_into() };
(x.clone(), x)
}
pub fn one<T>(start: T) -> Read<P> where T: PersistentInto<Arc<P::Value>> {
Read { data: start.persistent_into() }
}
}
impl<P: Key> Write<P> where P::Value: Send {
pub fn both<T>(start: T) -> (Write<P>, Write<P>) where T: PersistentInto<Arc<Mutex<P::Value>>> {
let x = Write { data: start.persistent_into() };
(x.clone(), x)
}
pub fn one<T>(start: T) -> Write<P> where T: PersistentInto<Arc<Mutex<P::Value>>> {
Write { data: start.persistent_into() }
}
}