<commit_before>use std::collections::btree_map::Entry;
use std::collections::*;
use std::fmt::{Error as FmtError, Formatter};
use std::ops::Deref;
use std::vec::*;

use serde::de;
use serde::de::Error;
use serde::ser::SerializeMap;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
//use serde::de::Deserialize;
use super::link::HalLink;
use super::{HalError, HalResult};
use serde_json::{from_value, to_value, Map, Value as JsonValue};

/// A Simple wrapper around a vector to allow custom
/// serialization when only 1 element is contained.
///
/// # example
///
/// In the example below, the vector serializes to json as an object if it contains
/// only one value, but as an array if more than one.
///
/// ```rust
/// # extern crate serde_json;
/// # extern crate rustic_hal;
/// use rustic_hal::resource::OneOrMany;
/// use rustic_hal::HalLink;
///
/// use serde_json::to_string;
/// # fn main() {
/// let mut v = OneOrMany::new();
/// v.push(&HalLink::new("http://test.com"));
///
/// assert_eq!(to_string(&v).unwrap(), r#"{"href":"http://test.com"}"#);
///
/// v.push(&HalLink::new("http://test2.com"));
///
/// assert_eq!(to_string(&v).unwrap(), r#"[{"href":"http://test.com"},{"href":"http://test2.com"}]"#);
/// # }
/// ```
#[derive(Clone)]
pub struct OneOrMany<T> {
    force_many: bool,
    content: Vec<Box<T>>,
}

impl<T> OneOrMany<T>
where
    T: Clone,
{
    /// create a new empty object
    pub fn new() -> OneOrMany<T> {
        OneOrMany {
            content: Vec::new(),
            force_many: false,
        }
    }

    /// Force to be serialized as array, even if only one element
    pub fn force_many(mut self) -> Self {
        self.force_many = true;
        self
    }

    /// retrieve the length of the wrapped vector
    pub fn len(&self) -> usize {
        self.content.len()
    }

    pub fn is_empty(&self) -> bool {
        self.content.is_empty()
    }

    /// Retrieves a single element if possible.
    ///
    pub fn single(&self) -> Option<&T> {
        if self.is_empty() {
            None
        } else {
            Some(self.content[0].deref())
        }
    }

    /// Returns an immutable reference to the
    /// contained links
    pub fn many(&self) -> &Vec<Box<T>> {
        &self.content
    }

    /// Add an element to the wrapped vector.
    pub fn push(&mut self, newval: &T) {
        self.content.push(Box::new(newval.clone()));
    }
}

impl<T> Serialize for OneOrMany<T>
where
    T: Serialize + Clone,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        if self.is_empty() {
            ().serialize(serializer)
        } else if self.len() == 1 && !self.force_many {
            self.single().serialize(serializer)
        } else {
            self.content.serialize(serializer)
        }
    }
}

impl<'de, T> Deserialize<'de> for OneOrMany<T>
where
    for<'d> T: Deserialize<'d> + Clone,
{
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let value: JsonValue = try!(Deserialize::deserialize(deserializer));
        let v2 = value.clone();
        match v2 {
            JsonValue::Object(_) => {
                let obj: T = match from_value(value) {
                    Ok(v) => from_value(v).unwrap(),
                    Err(e) => return Err(D::Error::custom(format!("JSON Error: {:?}", e))),
                };
                let mut res = OneOrMany::new();
                res.push(&obj);
                Ok(res)
            }
            JsonValue::Array(_) => {
                let obj: Vec<Box<T>> = match from_value(value) {
                    Ok(v) => from_value(v).unwrap(),
                    Err(e) => return Err(D::Error::custom(format!("JSON Error: {:?}", e))),
                };
                let mut res = OneOrMany::new();
                res.content = obj;
                Ok(res)
            }
            _ => Ok(OneOrMany::new()),
        }
    }
}

/// The HAL Resource structure.
///
///
#[derive(Clone)]
pub struct HalResource {
    /// Map of links to related resources.
    links: BTreeMap<String, OneOrMany<HalLink>>,
    /// Map of set of embedded resources.
    embedded: BTreeMap<String, OneOrMany<HalResource>>,
    /// Documentations Curies
    curies: BTreeMap<String, HalLink>,
    /// The actual resource data
    data: JsonValue,
}

impl HalResource {
    pub fn new<T>(payload: T) -> HalResource
    where
        T: Serialize,
    {
        HalResource {
            links: BTreeMap::new(),
            embedded: BTreeMap::new(),
            curies: BTreeMap::new(),
            data: to_value(payload).unwrap(),
        }
    }

    pub fn with_link<S, L>(&mut self, name: S, link: L) -> &mut Self
    where
        S: Into<String>,
        L: Into<HalLink>,
    {
        let lk_name = name.into();
        match self.links.entry(lk_name.clone()) {
            Entry::Vacant(entry) => {
                let mut lk = OneOrMany::new();

                let mut lk = match lk_name.as_ref() {
                    "curies" => lk.force_many(),
                    _ => lk,
                };

                lk.push(&(link.into()));
                entry.insert(lk);
            }
            Entry::Occupied(mut entry) => {
                let mut content = entry.get_mut(); //&mut HalLinks
                content.push(&(link.into()));
            }
        }
        self
    }

    /// Retrieve one named link if found. Returns the first one if more than one.
    pub fn get_link(&self, name: &str) -> Option<&HalLink> {
        match self.links.get(name) {
            Some(link) => link.single(),
            None => None,
        }
    }

    /// Retrieve the self link
    pub fn get_self(&self) -> Option<&HalLink> {
        self.get_link("self")
    }

    /// Retrieve the list of links for a key
    pub fn get_links(&self, name: &str) -> Option<&Vec<Box<HalLink>>> {
        match self.links.get(name) {
            Some(link) => Some(link.many()),
            None => None,
        }
    }

    pub fn with_resource(&mut self, name: &str, resource: HalResource) -> &mut Self {
        match self.embedded.entry(name.to_string()) {
            Entry::Vacant(entry) => {
                let mut resources = OneOrMany::new();
                resources.push(&resource);
                entry.insert(resources);
            }
            Entry::Occupied(mut entry) => {
                let mut content = entry.get_mut(); //&mut HalLinks
                content.push(&resource);
            }
        }
        self
    }

    pub fn with_resources(&mut self, name: &str, resources: Vec<HalResource>) -> &mut Self {
        match self.embedded.entry(name.to_string()) {
            Entry::Vacant(entry) => {
                let mut _resources = OneOrMany::new().force_many();

                for resource in resources.iter() {
                    _resources.push(resource)
                }
                entry.insert(_resources);
            }
            Entry::Occupied(mut entry) => {
                let mut content = entry.get_mut(); //&mut HalLinks

                for resource in resources.iter() {
                    content.push(&resource);
                }
            }
        }
        self
    }

    pub fn with_curie(&mut self, name: &str, href: &str) -> &mut Self {
        self.with_link("curies", HalLink::new(href).templated(true).with_name(name));
        self
    }

    pub fn with_extra_data<V>(&mut self, name: &str, value: V) -> &mut Self
    where
        V: Serialize,
    {
        match self.data {
            JsonValue::Object(ref mut m) => {
                m.insert(name.to_string(), to_value(value).unwrap());
            }
            _ => {
                let mut data = Map::<String, JsonValue>::new();
                data.insert(name.to_string(), to_value(value).unwrap());
                self.data = JsonValue::Object(data);
            }
        };
        self
    }

    pub fn get_extra_data<V>(&self, name: &str) -> HalResult<V>
    where
        for<'de> V: Deserialize<'de>,
    {
        let data = match self.data {
            JsonValue::Object(ref m) => m,
            _ => return Err(HalError::Custom("Invalid payload".to_string())),
        };
        match data.get(name) {
            Some(v) => from_value::<V>(v.clone()).or_else(|e| Err(HalError::Json(e))),
            None => Err(HalError::Custom(format!("Key {} missing in payload", name))),
        }
    }

    pub fn get_data<V>(&self) -> HalResult<V>
    where
        for<'de> V: Deserialize<'de>,
    {
        from_value::<V>(self.data.clone()).or_else(|e| Err(HalError::Json(e)))
    }
}

impl Serialize for HalResource {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let map = match self.data {
            JsonValue::Object(ref m) => Some(m),
            _ => None,
        };
        let mut length = match map {
            Some(m) => m.len(),
            _ => 0,
        };
        length += self.links.len();
        length += self.embedded.len();

        let mut state = try!(serializer.serialize_map(Some(length)));
        if !self.links.is_empty() {
            try!(state.serialize_key("_links"));
            try!(state.serialize_value(&(self.links)));
        }
        if !self.embedded.is_empty() {
            try!(state.serialize_key("_embedded"));
            try!(state.serialize_value(&(self.embedded)));
        }
        if let Some(map) = map {
            for (k, v) in map {
                try!(state.serialize_key(k));
                try!(state.serialize_value(v));
            }
        };

        state.end()
    }
}

impl<'de> Deserialize<'de> for HalResource {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct ResourceVisitor {}

        impl ResourceVisitor {
            fn new() -> Self {
                ResourceVisitor {}
            }
        }

        /// A visitor for deserializing `HalResource` from map representation.
        ///
        /// Implementation deserialize the hal specific keys (_links, _embedded) to maps
        /// as usual, and stores everything else in  a `JsonValue` object.
        /// It then converts the `JsonValue` to the type T
        impl<'de> de::Visitor<'de> for ResourceVisitor {
            type Value = HalResource;
            fn expecting(&self, f: &mut Formatter) -> Result<(), FmtError> {
                Ok(())
            }

            fn visit_map<M>(self, mut visitor: M) -> Result<HalResource, M::Error>
            where
                M: de::MapAccess<'de>,
            {
                //transitory Value to read the data.
                let mut payload: Map<String, JsonValue> = Map::new();
                // Dummy resource to collect the links and embedded resources
                let mut resource: HalResource = HalResource::new(());
                while let Some(key) = try!(visitor.next_key::<String>()) {
                    match key.deref() {
                        "_links" => {
                            resource.links = try!(visitor.next_value());
                        }
                        "_embedded" => {
                            resource.embedded = try!(visitor.next_value());
                        }
                        _ => {
                            payload.insert(key, try!(visitor.next_value()));
                        }
                    }
                }
                //try!(visitor.end());
                resource.data = JsonValue::Object(payload);
                Ok(resource)
            }
        }

        deserializer.deserialize_map(ResourceVisitor::new())
    }
}

impl PartialEq for HalResource {
    fn eq(&self, other: &HalResource) -> bool {
        self.get_self() == other.get_self()
    }
}
<commit_msg>Force serialization to empty object if force_many<commit_after>use std::collections::btree_map::Entry;
use std::collections::*;
use std::fmt::{Error as FmtError, Formatter};
use std::ops::Deref;
use std::vec::*;

use serde::de;
use serde::de::Error;
use serde::ser::SerializeMap;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
//use serde::de::Deserialize;
use super::link::HalLink;
use super::{HalError, HalResult};
use serde_json::{from_value, to_value, Map, Value as JsonValue};

/// A Simple wrapper around a vector to allow custom
/// serialization when only 1 element is contained.
///
/// # example
///
/// In the example below, the vector serializes to json as an object if it contains
/// only one value, but as an array if more than one.
///
/// ```rust
/// # extern crate serde_json;
/// # extern crate rustic_hal;
/// use rustic_hal::resource::OneOrMany;
/// use rustic_hal::HalLink;
///
/// use serde_json::to_string;
/// # fn main() {
/// let mut v = OneOrMany::new();
/// v.push(&HalLink::new("http://test.com"));
///
/// assert_eq!(to_string(&v).unwrap(), r#"{"href":"http://test.com"}"#);
///
/// v.push(&HalLink::new("http://test2.com"));
///
/// assert_eq!(to_string(&v).unwrap(), r#"[{"href":"http://test.com"},{"href":"http://test2.com"}]"#);
/// # }
/// ```
#[derive(Clone)]
pub struct OneOrMany<T> {
    force_many: bool,
    content: Vec<Box<T>>,
}

impl<T> OneOrMany<T>
where
    T: Clone,
{
    /// create a new empty object
    pub fn new() -> OneOrMany<T> {
        OneOrMany {
            content: Vec::new(),
            force_many: false,
        }
    }

    /// Force to be serialized as array, even if only one element
    pub fn force_many(mut self) -> Self {
        self.force_many = true;
        self
    }

    /// retrieve the length of the wrapped vector
    pub fn len(&self) -> usize {
        self.content.len()
    }

    pub fn is_empty(&self) -> bool {
        self.content.is_empty()
    }

    /// Retrieves a single element if possible.
    ///
    pub fn single(&self) -> Option<&T> {
        if self.is_empty() {
            None
        } else {
            Some(self.content[0].deref())
        }
    }

    /// Returns an immutable reference to the
    /// contained links
    pub fn many(&self) -> &Vec<Box<T>> {
        &self.content
    }

    /// Add an element to the wrapped vector.
    pub fn push(&mut self, newval: &T) {
        self.content.push(Box::new(newval.clone()));
    }
}

impl<T> Serialize for OneOrMany<T>
where
    T: Serialize + Clone,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        if self.is_empty() && !self.force_many {
            ().serialize(serializer)
        } else if self.len() == 1 && !self.force_many {
            self.single().serialize(serializer)
        } else {
            self.content.serialize(serializer)
        }
    }
}

impl<'de, T> Deserialize<'de> for OneOrMany<T>
where
    for<'d> T: Deserialize<'d> + Clone,
{
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let value: JsonValue = try!(Deserialize::deserialize(deserializer));
        let v2 = value.clone();
        match v2 {
            JsonValue::Object(_) => {
                let obj: T = match from_value(value) {
                    Ok(v) => from_value(v).unwrap(),
                    Err(e) => return Err(D::Error::custom(format!("JSON Error: {:?}", e))),
                };
                let mut res = OneOrMany::new();
                res.push(&obj);
                Ok(res)
            }
            JsonValue::Array(_) => {
                let obj: Vec<Box<T>> = match from_value(value) {
                    Ok(v) => from_value(v).unwrap(),
                    Err(e) => return Err(D::Error::custom(format!("JSON Error: {:?}", e))),
                };
                let mut res = OneOrMany::new();
                res.content = obj;
                Ok(res)
            }
            _ => Ok(OneOrMany::new()),
        }
    }
}

/// The HAL Resource structure.
///
///
#[derive(Clone)]
pub struct HalResource {
    /// Map of links to related resources.
    links: BTreeMap<String, OneOrMany<HalLink>>,
    /// Map of set of embedded resources.
    embedded: BTreeMap<String, OneOrMany<HalResource>>,
    /// Documentations Curies
    curies: BTreeMap<String, HalLink>,
    /// The actual resource data
    data: JsonValue,
}

impl HalResource {
    pub fn new<T>(payload: T) -> HalResource
    where
        T: Serialize,
    {
        HalResource {
            links: BTreeMap::new(),
            embedded: BTreeMap::new(),
            curies: BTreeMap::new(),
            data: to_value(payload).unwrap(),
        }
    }

    pub fn with_link<S, L>(&mut self, name: S, link: L) -> &mut Self
    where
        S: Into<String>,
        L: Into<HalLink>,
    {
        let lk_name = name.into();
        match self.links.entry(lk_name.clone()) {
            Entry::Vacant(entry) => {
                let mut lk = OneOrMany::new();

                let mut lk = match lk_name.as_ref() {
                    "curies" => lk.force_many(),
                    _ => lk,
                };

                lk.push(&(link.into()));
                entry.insert(lk);
            }
            Entry::Occupied(mut entry) => {
                let mut content = entry.get_mut(); //&mut HalLinks
                content.push(&(link.into()));
            }
        }
        self
    }

    /// Retrieve one named link if found. Returns the first one if more than one.
    pub fn get_link(&self, name: &str) -> Option<&HalLink> {
        match self.links.get(name) {
            Some(link) => link.single(),
            None => None,
        }
    }

    /// Retrieve the self link
    pub fn get_self(&self) -> Option<&HalLink> {
        self.get_link("self")
    }

    /// Retrieve the list of links for a key
    pub fn get_links(&self, name: &str) -> Option<&Vec<Box<HalLink>>> {
        match self.links.get(name) {
            Some(link) => Some(link.many()),
            None => None,
        }
    }

    pub fn with_resource(&mut self, name: &str, resource: HalResource) -> &mut Self {
        match self.embedded.entry(name.to_string()) {
            Entry::Vacant(entry) => {
                let mut resources = OneOrMany::new();
                resources.push(&resource);
                entry.insert(resources);
            }
            Entry::Occupied(mut entry) => {
                let mut content = entry.get_mut(); //&mut HalLinks
                content.push(&resource);
            }
        }
        self
    }

    pub fn with_resources(&mut self, name: &str, resources: Vec<HalResource>) -> &mut Self {
        match self.embedded.entry(name.to_string()) {
            Entry::Vacant(entry) => {
                let mut _resources = OneOrMany::new().force_many();

                for resource in resources.iter() {
                    _resources.push(resource)
                }
                entry.insert(_resources);
            }
            Entry::Occupied(mut entry) => {
                let mut content = entry.get_mut(); //&mut HalLinks

                for resource in resources.iter() {
                    content.push(&resource);
                }
            }
        }
        self
    }

    pub fn with_curie(&mut self, name: &str, href: &str) -> &mut Self {
        self.with_link("curies", HalLink::new(href).templated(true).with_name(name));
        self
    }

    pub fn with_extra_data<V>(&mut self, name: &str, value: V) -> &mut Self
    where
        V: Serialize,
    {
        match self.data {
            JsonValue::Object(ref mut m) => {
                m.insert(name.to_string(), to_value(value).unwrap());
            }
            _ => {
                let mut data = Map::<String, JsonValue>::new();
                data.insert(name.to_string(), to_value(value).unwrap());
                self.data = JsonValue::Object(data);
            }
        };
        self
    }

    pub fn get_extra_data<V>(&self, name: &str) -> HalResult<V>
    where
        for<'de> V: Deserialize<'de>,
    {
        let data = match self.data {
            JsonValue::Object(ref m) => m,
            _ => return Err(HalError::Custom("Invalid payload".to_string())),
        };
        match data.get(name) {
            Some(v) => from_value::<V>(v.clone()).or_else(|e| Err(HalError::Json(e))),
            None => Err(HalError::Custom(format!("Key {} missing in payload", name))),
        }
    }

    pub fn get_data<V>(&self) -> HalResult<V>
    where
        for<'de> V: Deserialize<'de>,
    {
        from_value::<V>(self.data.clone()).or_else(|e| Err(HalError::Json(e)))
    }
}

impl Serialize for HalResource {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let map = match self.data {
            JsonValue::Object(ref m) => Some(m),
            _ => None,
        };
        let mut length = match map {
            Some(m) => m.len(),
            _ => 0,
        };
        length += self.links.len();
        length += self.embedded.len();

        let mut state = try!(serializer.serialize_map(Some(length)));
        if !self.links.is_empty() {
            try!(state.serialize_key("_links"));
            try!(state.serialize_value(&(self.links)));
        }
        if !self.embedded.is_empty() {
            try!(state.serialize_key("_embedded"));
            try!(state.serialize_value(&(self.embedded)));
        }
        if let Some(map) = map {
            for (k, v) in map {
                try!(state.serialize_key(k));
                try!(state.serialize_value(v));
            }
        };

        state.end()
    }
}

impl<'de> Deserialize<'de> for HalResource {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct ResourceVisitor {}

        impl ResourceVisitor {
            fn new() -> Self {
                ResourceVisitor {}
            }
        }

        /// A visitor for deserializing `HalResource` from map representation.
        ///
        /// Implementation deserialize the hal specific keys (_links, _embedded) to maps
        /// as usual, and stores everything else in  a `JsonValue` object.
        /// It then converts the `JsonValue` to the type T
        impl<'de> de::Visitor<'de> for ResourceVisitor {
            type Value = HalResource;
            fn expecting(&self, f: &mut Formatter) -> Result<(), FmtError> {
                Ok(())
            }

            fn visit_map<M>(self, mut visitor: M) -> Result<HalResource, M::Error>
            where
                M: de::MapAccess<'de>,
            {
                //transitory Value to read the data.
                let mut payload: Map<String, JsonValue> = Map::new();
                // Dummy resource to collect the links and embedded resources
                let mut resource: HalResource = HalResource::new(());
                while let Some(key) = try!(visitor.next_key::<String>()) {
                    match key.deref() {
                        "_links" => {
                            resource.links = try!(visitor.next_value());
                        }
                        "_embedded" => {
                            resource.embedded = try!(visitor.next_value());
                        }
                        _ => {
                            payload.insert(key, try!(visitor.next_value()));
                        }
                    }
                }
                //try!(visitor.end());
                resource.data = JsonValue::Object(payload);
                Ok(resource)
            }
        }

        deserializer.deserialize_map(ResourceVisitor::new())
    }
}

impl PartialEq for HalResource {
    fn eq(&self, other: &HalResource) -> bool {
        self.get_self() == other.get_self()
    }
}
<|endoftext|>


<commit_before>//!Response writers.

use std;
use std::io::{self, Write};
use std::error;
use std::borrow::Cow;
use std::convert::From;
use std::str::{from_utf8, Utf8Error};
use std::string::{FromUtf8Error};

use hyper;
use hyper::header::{Headers, Header, HeaderFormat};
use hyper::net::Fresh;
use hyper::http::h1::HttpWriter;
use hyper::version::HttpVersion;

use anymap::AnyMap;

use StatusCode;

use filter::{FilterContext, ResponseFilter};
use filter::ResponseAction as Action;
use log::Log;

use Global;

///The result of a response action.
#[derive(Debug)]
pub enum Error {
    ///A response filter failed.
    Filter(String),

    ///There was an IO error.
    Io(io::Error)
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match *self {
            Error::Filter(ref desc) => write!(f, "filter error: {}", desc),
            Error::Io(ref e) => write!(f, "io error: {}", e)
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Filter(ref desc) => desc,
            Error::Io(ref e) => e.description()
        }
    }

    fn cause(&self) -> Option<&std::error::Error> {
        match *self {
            Error::Filter(_) => None,
            Error::Io(ref e) => Some(e)
        }
    }
}

///Unified representation of response data.
pub enum Data<'a> {
    ///Data in byte form.
    Bytes(Cow<'a, [u8]>),

    ///Data in string form.
    String(Cow<'a, str>)
}

impl<'a> Data<'a> {
    ///Borrow the content as a byte slice.
    pub fn as_bytes(&self) -> &[u8] {
        match self {
            &Data::Bytes(ref bytes) => bytes,
            &Data::String(ref string) => string.as_bytes(),
        }
    }

    ///Turns the content into a byte vector. Slices are copied.
    pub fn into_bytes(self) -> Vec<u8> {
        match self {
            Data::Bytes(bytes) => bytes.into_owned(),
            Data::String(string) => string.into_owned().into_bytes()
        }
    }

    ///Borrow the content as a UTF-8 string slice, if possible.
    pub fn as_string(&self) -> Result<&str, Utf8Error> {
        match self {
            &Data::Bytes(ref bytes) => from_utf8(bytes),
            &Data::String(ref string) => Ok(string),
        }
    }

    ///Turn the content into a UTF-8 string, if possible. Slices are copied.
    pub fn into_string(self) -> Result<String, FromUtf8Error> {
        match self {
            Data::Bytes(bytes) => String::from_utf8(bytes.into_owned()),
            Data::String(string) => Ok(string.into_owned())
        }
    }
}

impl<'a> Into<Data<'a>> for Vec<u8> {
    fn into(self) -> Data<'a> {
        Data::Bytes(Cow::Owned(self))
    }
}

impl<'a> Into<Data<'a>> for &'a [u8] {
    fn into(self) -> Data<'a> {
        Data::Bytes(Cow::Borrowed(self))
    }
}

impl<'a> Into<Data<'a>> for String {
    fn into(self) -> Data<'a> {
        Data::String(Cow::Owned(self))
    }
}

impl<'a> Into<Data<'a>> for &'a str {
    fn into(self) -> Data<'a> {
        Data::String(Cow::Borrowed(self))
    }
}

///An interface for setting HTTP status code and response headers, before data gets written to the client.
pub struct Response<'a, 'b> {
    headers: Option<&'a mut Headers>,

    status: Option<StatusCode>,

    version: Option<HttpVersion>,
    writer: Option<HttpWriter<&'a mut (io::Write + 'a)>>,
    filters: &'b Vec<Box<ResponseFilter>>,
    log: &'b (Log + 'b),
    global: &'b Global,
    filter_storage: Option<AnyMap>
}

impl<'a, 'b> Response<'a, 'b> {
    pub fn new(
        response: hyper::server::response::Response<'a>,
        filters: &'b Vec<Box<ResponseFilter>>,
        log: &'b Log,
        global: &'b Global
    ) -> Response<'a, 'b> {
        let (version, writer, status, headers) = response.deconstruct();
        Response {
            headers: Some(headers),
            status: Some(status),
            version: Some(version),
            writer: Some(writer),
            filters: filters,
            log: log,
            global: global,
            filter_storage: Some(AnyMap::new())
        }
    }

    ///Set HTTP status code. Ok (200) is default.
    pub fn set_status(&mut self, status: StatusCode) {
        self.status = Some(status);
    }

    ///Set a HTTP response header. Date, content type (text/plain) and server is automatically set.
    pub fn set_header<H: Header + HeaderFormat>(&mut self, header: H) {
        if let Some(ref mut headers) = self.headers {
            headers.set(header);
        }
    }

    ///Get a HTTP response header if set.
    pub fn get_header<H: Header + HeaderFormat>(&self) -> Option<&H> {
        self.headers.as_ref().and_then(|h| h.get::<H>())
    }

    ///Mutably borrow the filter storage. It can be used to communicate with
    ///the response filters.
    pub fn filter_storage(&mut self) -> &mut AnyMap {
        self.filter_storage.as_mut().expect("response used after drop")
    }

    ///Turn the `Response` into a `ResponseWriter` to allow the response body to be written.
    ///
    ///Status code and headers will be written to the client and `ResponseFilter::begin()`
    ///will be called on the registered response filters.
    pub fn into_writer(mut self) -> ResponseWriter<'a, 'b> {
        self.make_writer()
    }

    fn make_writer(&mut self) -> ResponseWriter<'a, 'b> {
        let mut write_queue = Vec::new();
        let mut header_result = (self.status.take().unwrap(), self.headers.take().unwrap(), Action::Next(None));

        for filter in self.filters {
            header_result = match header_result {
                (_, _, Action::SilentAbort) => break,
                (_, _, Action::Abort(_)) => break,
                (status, headers, r) => {
                    write_queue.push(r);

                    let filter_res = {
                        let filter_context = FilterContext {
                            storage: self.filter_storage(),
                            log: self.log,
                            global: self.global,
                        };
                        filter.begin(filter_context, status, headers)
                    };

                    match filter_res {
                        (status, Action::Abort(e)) => (status, headers, Action::Abort(e)),
                        (status, result) => {
                            let mut error = None;

                            write_queue = write_queue.into_iter().filter_map(|action| match action {
                                Action::Next(content) => {
                                    let filter_context = FilterContext {
                                        storage: self.filter_storage(),
                                        log: self.log,
                                        global: self.global,
                                    };
                                    Some(filter.write(filter_context, content))
                                },
                                Action::SilentAbort => None,
                                Action::Abort(e) => {
                                    error = Some(e);
                                    None
                                }
                            }).collect();

                            match error {
                                Some(e) => (status, headers, Action::Abort(e)),
                                None => (status, headers, result)
                            }
                        }
                    }
                }
            }
        }

        let writer = match header_result {
            (_, _, Action::Abort(e)) => Err(Error::Filter(e)),
            (status, headers, last_result) => {
                write_queue.push(last_result);

                let version = self.version.take().unwrap();
                let writer = self.writer.take().unwrap();
                let writer = hyper::server::response::Response::<Fresh>::construct(version, writer, status, headers).start();
                let mut writer = match writer {
                    Ok(writer) => Ok(writer),
                    Err(e) => Err(Error::Io(e))
                };

                for action in write_queue {
                    writer = match (action, writer) {
                        (Action::Next(Some(content)), Ok(mut writer)) => match writer.write_all(content.as_bytes()) {
                            Ok(_) => Ok(writer),
                            Err(e) => Err(Error::Io(e))
                        },
                        (Action::Abort(e), _) => Err(Error::Filter(e)),
                        (_, writer) => writer
                    };
                }

                writer
            }
        };

        ResponseWriter {
            writer: Some(writer),
            filters: self.filters,
            log: self.log,
            global: self.global,
            filter_storage: self.filter_storage.take().expect("response used after drop")
        }
    }
}

#[allow(unused_must_use)]
impl<'a, 'b> Drop for Response<'a, 'b> {
    ///Writes status code and headers and closes the connection.
    fn drop(&mut self) {
        if self.writer.is_some() {
            self.make_writer();
        }
    }
}

///An interface for writing to the response body.
pub struct ResponseWriter<'a, 'b> {
    writer: Option<Result<hyper::server::response::Response<'a, hyper::net::Streaming>, Error>>,
    filters: &'b Vec<Box<ResponseFilter>>,
    log: &'b (Log + 'b),
    global: &'b Global,
    filter_storage: AnyMap
}

impl<'a, 'b> ResponseWriter<'a, 'b> {

    ///Mutably borrow the filter storage. It can be used to communicate with
    ///the response filters.
    pub fn filter_storage(&mut self) -> &mut AnyMap {
        &mut self.filter_storage
    }

    ///Write response body data to the client.
    ///
    ///Any errors that occures while writing the data will be ignored. Use
    ///`try_send`, instead, to also get error information.
    #[allow(unused_must_use)]
    pub fn send<'d, Content: Into<Data<'d>>>(&mut self, content: Content) {
        self.try_send(content);
    }

    ///Write response body data to the client and receive the number of
    ///written bytes, or any error that occured.
    pub fn try_send<'d, Content: Into<Data<'d>>>(&mut self, content: Content) -> Result<usize, Error> {
        let mut writer = match self.writer {
            Some(Ok(ref mut writer)) => writer,
            None => return Err(Error::Io(io::Error::new(io::ErrorKind::BrokenPipe, "write after close"))),
            Some(Err(_)) => if let Some(Err(e)) = self.writer.take() {
                return Err(e);
            } else { unreachable!(); }
        };

        let mut filter_result = Action::next(Some(content));

        for filter in self.filters {
            filter_result = match filter_result {
                Action::Next(content) => {
                    let filter_context = FilterContext {
                        storage: &mut self.filter_storage,
                        log: self.log,
                        global: self.global,
                    };
                    filter.write(filter_context, content)
                },
                _ => break
            }
        }

        let write_result = match filter_result {
            Action::Next(Some(ref s)) => {
                let buf = s.as_bytes();
                match writer.write_all(buf) {
                    Ok(()) => Some(Ok(buf.len())),
                    Err(e) => Some(Err(e))
                }
            },
            _ => None
        };

        match write_result {
            Some(Ok(l)) => Ok(l),
            Some(Err(e)) => Err(Error::Io(e)),
            None => match filter_result {
                Action::Abort(e) => Err(Error::Filter(e)),
                Action::Next(None) => Ok(0),
                _ => unreachable!()
            }
        }
    }

    ///Finish writing the response and collect eventual errors.
    ///
    ///This is optional and will happen silently when the writer drops out of
    ///scope.
    pub fn end(mut self) -> Result<(), Error> {
        self.finish()
    }

    fn finish(&mut self) -> Result<(), Error> {
        let mut writer = try!(self.writer.take().expect("can only finish once"));
        let mut write_queue: Vec<Action> = Vec::new();

        for filter in self.filters {
            let mut error = None;
            write_queue = write_queue.into_iter().filter_map(|action| match action {
                Action::Next(content) => {
                    let filter_context = FilterContext {
                        storage: &mut self.filter_storage,
                        log: self.log,
                        global: self.global,
                    };
                    Some(filter.write(filter_context, content))
                },
                Action::SilentAbort => None,
                Action::Abort(e) => {
                    error = Some(e);
                    None
                }
            }).collect();

            match error {
                Some(e) => return Err(Error::Filter(e)),
                None => {
                    let filter_context = FilterContext {
                        storage: &mut self.filter_storage,
                        log: self.log,
                        global: self.global,
                    };
                    write_queue.push(filter.end(filter_context))
                }
            }
        }

        for action in write_queue {
            try!{
                match action {
                    Action::Next(Some(content)) => writer.write_all(content.as_bytes()),
                    Action::Abort(e) => return Err(Error::Filter(e)),
                    _ => Ok(())
                }
            }
        }

        writer.end().map_err(|e| Error::Io(e))
    }

    fn borrow_writer(&mut self) -> Result<&mut hyper::server::response::Response<'a, hyper::net::Streaming>, Error> {
        match self.writer {
            Some(Ok(ref mut writer)) => Ok(writer),
            None => Err(Error::Io(io::Error::new(io::ErrorKind::BrokenPipe, "write after close"))),
            Some(Err(_)) => if let Some(Err(e)) = self.writer.take() {
                Err(e)
            } else { unreachable!(); }
        }
    }
}

impl<'a, 'b> Write for ResponseWriter<'a, 'b> {
    fn write(&mut self, content: &[u8]) -> io::Result<usize> {
        response_to_io_result(self.try_send(content))
    }

    fn write_all(&mut self, content: &[u8]) -> io::Result<()> {
        self.write(content).map(|_| ())
    }

    fn flush(&mut self) -> io::Result<()> {
        let mut writer = try!(response_to_io_result(self.borrow_writer()));
        writer.flush()
    }
}

#[allow(unused_must_use)]
impl<'a, 'b> Drop for ResponseWriter<'a, 'b> {
    ///Finishes writing and closes the connection.
    fn drop(&mut self) {
        if self.writer.is_some() {
            self.finish();
        }
    }
}

fn response_to_io_result<T>(res:  Result<T, Error>) -> io::Result<T> {
    match res {
        Ok(v) => Ok(v),
        Err(Error::Io(e)) => Err(e),
        Err(e) => Err(io::Error::new(io::ErrorKind::Other, e))
    }
}<commit_msg>Don't deconstruct the Hyper Response in Response<commit_after>//!Response writers.

use std;
use std::io::{self, Write};
use std::error;
use std::borrow::Cow;
use std::convert::From;
use std::str::{from_utf8, Utf8Error};
use std::string::{FromUtf8Error};

use hyper;
use hyper::header::{Header, HeaderFormat};

use anymap::AnyMap;

use StatusCode;

use filter::{FilterContext, ResponseFilter};
use filter::ResponseAction as Action;
use log::Log;

use Global;

///The result of a response action.
#[derive(Debug)]
pub enum Error {
    ///A response filter failed.
    Filter(String),

    ///There was an IO error.
    Io(io::Error)
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match *self {
            Error::Filter(ref desc) => write!(f, "filter error: {}", desc),
            Error::Io(ref e) => write!(f, "io error: {}", e)
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Filter(ref desc) => desc,
            Error::Io(ref e) => e.description()
        }
    }

    fn cause(&self) -> Option<&std::error::Error> {
        match *self {
            Error::Filter(_) => None,
            Error::Io(ref e) => Some(e)
        }
    }
}

///Unified representation of response data.
pub enum Data<'a> {
    ///Data in byte form.
    Bytes(Cow<'a, [u8]>),

    ///Data in string form.
    String(Cow<'a, str>)
}

impl<'a> Data<'a> {
    ///Borrow the content as a byte slice.
    pub fn as_bytes(&self) -> &[u8] {
        match self {
            &Data::Bytes(ref bytes) => bytes,
            &Data::String(ref string) => string.as_bytes(),
        }
    }

    ///Turns the content into a byte vector. Slices are copied.
    pub fn into_bytes(self) -> Vec<u8> {
        match self {
            Data::Bytes(bytes) => bytes.into_owned(),
            Data::String(string) => string.into_owned().into_bytes()
        }
    }

    ///Borrow the content as a UTF-8 string slice, if possible.
    pub fn as_string(&self) -> Result<&str, Utf8Error> {
        match self {
            &Data::Bytes(ref bytes) => from_utf8(bytes),
            &Data::String(ref string) => Ok(string),
        }
    }

    ///Turn the content into a UTF-8 string, if possible. Slices are copied.
    pub fn into_string(self) -> Result<String, FromUtf8Error> {
        match self {
            Data::Bytes(bytes) => String::from_utf8(bytes.into_owned()),
            Data::String(string) => Ok(string.into_owned())
        }
    }
}

impl<'a> Into<Data<'a>> for Vec<u8> {
    fn into(self) -> Data<'a> {
        Data::Bytes(Cow::Owned(self))
    }
}

impl<'a> Into<Data<'a>> for &'a [u8] {
    fn into(self) -> Data<'a> {
        Data::Bytes(Cow::Borrowed(self))
    }
}

impl<'a> Into<Data<'a>> for String {
    fn into(self) -> Data<'a> {
        Data::String(Cow::Owned(self))
    }
}

impl<'a> Into<Data<'a>> for &'a str {
    fn into(self) -> Data<'a> {
        Data::String(Cow::Borrowed(self))
    }
}

///An interface for setting HTTP status code and response headers, before data gets written to the client.
pub struct Response<'a, 'b> {
    writer: Option<hyper::server::response::Response<'a>>,
    filters: &'b Vec<Box<ResponseFilter>>,
    log: &'b (Log + 'b),
    global: &'b Global,
    filter_storage: Option<AnyMap>
}

impl<'a, 'b> Response<'a, 'b> {
    pub fn new(
        response: hyper::server::response::Response<'a>,
        filters: &'b Vec<Box<ResponseFilter>>,
        log: &'b Log,
        global: &'b Global
    ) -> Response<'a, 'b> {
        Response {
            writer: Some(response),
            filters: filters,
            log: log,
            global: global,
            filter_storage: Some(AnyMap::new())
        }
    }

    ///Set HTTP status code. Ok (200) is default.
    pub fn set_status(&mut self, status: StatusCode) {
        if let Some(ref mut writer) = self.writer {
            *writer.status_mut() = status;
        }
    }

    ///Set a HTTP response header. Date, content type (text/plain) and server is automatically set.
    pub fn set_header<H: Header + HeaderFormat>(&mut self, header: H) {
        if let Some(ref mut writer) = self.writer {
            writer.headers_mut().set(header);
        }
    }

    ///Get a HTTP response header if set.
    pub fn get_header<H: Header + HeaderFormat>(&self) -> Option<&H> {
        self.writer.as_ref().and_then(|w| w.headers().get())
    }

    ///Mutably borrow the filter storage. It can be used to communicate with
    ///the response filters.
    pub fn filter_storage(&mut self) -> &mut AnyMap {
        self.filter_storage.as_mut().expect("response used after drop")
    }

    ///Turn the `Response` into a `ResponseWriter` to allow the response body to be written.
    ///
    ///Status code and headers will be written to the client and `ResponseFilter::begin()`
    ///will be called on the registered response filters.
    pub fn into_writer(mut self) -> ResponseWriter<'a, 'b> {
        self.make_writer()
    }

    fn make_writer(&mut self) -> ResponseWriter<'a, 'b> {
        let mut write_queue = Vec::new();
        let mut writer = self.writer.take().expect("response used after drop");
        let mut header_result = (writer.status(), Action::Next(None));

        for filter in self.filters {
            header_result = match header_result {
                (_, Action::SilentAbort) => break,
                (_, Action::Abort(_)) => break,
                (status, r) => {
                    write_queue.push(r);

                    let filter_res = {
                        let filter_context = FilterContext {
                            storage: self.filter_storage(),
                            log: self.log,
                            global: self.global,
                        };
                        filter.begin(filter_context, status, writer.headers_mut())
                    };

                    match filter_res {
                        (status, Action::Abort(e)) => (status, Action::Abort(e)),
                        (status, result) => {
                            let mut error = None;

                            write_queue = write_queue.into_iter().filter_map(|action| match action {
                                Action::Next(content) => {
                                    let filter_context = FilterContext {
                                        storage: self.filter_storage(),
                                        log: self.log,
                                        global: self.global,
                                    };
                                    Some(filter.write(filter_context, content))
                                },
                                Action::SilentAbort => None,
                                Action::Abort(e) => {
                                    error = Some(e);
                                    None
                                }
                            }).collect();

                            match error {
                                Some(e) => (status, Action::Abort(e)),
                                None => (status, result)
                            }
                        }
                    }
                }
            }
        }

        let writer = match header_result {
            (_, Action::Abort(e)) => Err(Error::Filter(e)),
            (status, last_result) => {
                write_queue.push(last_result);

                *writer.status_mut() = status;
                let mut writer = match writer.start() {
                    Ok(writer) => Ok(writer),
                    Err(e) => Err(Error::Io(e))
                };

                for action in write_queue {
                    writer = match (action, writer) {
                        (Action::Next(Some(content)), Ok(mut writer)) => match writer.write_all(content.as_bytes()) {
                            Ok(_) => Ok(writer),
                            Err(e) => Err(Error::Io(e))
                        },
                        (Action::Abort(e), _) => Err(Error::Filter(e)),
                        (_, writer) => writer
                    };
                }

                writer
            }
        };

        ResponseWriter {
            writer: Some(writer),
            filters: self.filters,
            log: self.log,
            global: self.global,
            filter_storage: self.filter_storage.take().expect("response used after drop")
        }
    }
}

#[allow(unused_must_use)]
impl<'a, 'b> Drop for Response<'a, 'b> {
    ///Writes status code and headers and closes the connection.
    fn drop(&mut self) {
        if self.writer.is_some() {
            self.make_writer();
        }
    }
}

///An interface for writing to the response body.
pub struct ResponseWriter<'a, 'b> {
    writer: Option<Result<hyper::server::response::Response<'a, hyper::net::Streaming>, Error>>,
    filters: &'b Vec<Box<ResponseFilter>>,
    log: &'b (Log + 'b),
    global: &'b Global,
    filter_storage: AnyMap
}

impl<'a, 'b> ResponseWriter<'a, 'b> {

    ///Mutably borrow the filter storage. It can be used to communicate with
    ///the response filters.
    pub fn filter_storage(&mut self) -> &mut AnyMap {
        &mut self.filter_storage
    }

    ///Write response body data to the client.
    ///
    ///Any errors that occures while writing the data will be ignored. Use
    ///`try_send`, instead, to also get error information.
    #[allow(unused_must_use)]
    pub fn send<'d, Content: Into<Data<'d>>>(&mut self, content: Content) {
        self.try_send(content);
    }

    ///Write response body data to the client and receive the number of
    ///written bytes, or any error that occured.
    pub fn try_send<'d, Content: Into<Data<'d>>>(&mut self, content: Content) -> Result<usize, Error> {
        let mut writer = match self.writer {
            Some(Ok(ref mut writer)) => writer,
            None => return Err(Error::Io(io::Error::new(io::ErrorKind::BrokenPipe, "write after close"))),
            Some(Err(_)) => if let Some(Err(e)) = self.writer.take() {
                return Err(e);
            } else { unreachable!(); }
        };

        let mut filter_result = Action::next(Some(content));

        for filter in self.filters {
            filter_result = match filter_result {
                Action::Next(content) => {
                    let filter_context = FilterContext {
                        storage: &mut self.filter_storage,
                        log: self.log,
                        global: self.global,
                    };
                    filter.write(filter_context, content)
                },
                _ => break
            }
        }

        let write_result = match filter_result {
            Action::Next(Some(ref s)) => {
                let buf = s.as_bytes();
                match writer.write_all(buf) {
                    Ok(()) => Some(Ok(buf.len())),
                    Err(e) => Some(Err(e))
                }
            },
            _ => None
        };

        match write_result {
            Some(Ok(l)) => Ok(l),
            Some(Err(e)) => Err(Error::Io(e)),
            None => match filter_result {
                Action::Abort(e) => Err(Error::Filter(e)),
                Action::Next(None) => Ok(0),
                _ => unreachable!()
            }
        }
    }

    ///Finish writing the response and collect eventual errors.
    ///
    ///This is optional and will happen silently when the writer drops out of
    ///scope.
    pub fn end(mut self) -> Result<(), Error> {
        self.finish()
    }

    fn finish(&mut self) -> Result<(), Error> {
        let mut writer = try!(self.writer.take().expect("can only finish once"));
        let mut write_queue: Vec<Action> = Vec::new();

        for filter in self.filters {
            let mut error = None;
            write_queue = write_queue.into_iter().filter_map(|action| match action {
                Action::Next(content) => {
                    let filter_context = FilterContext {
                        storage: &mut self.filter_storage,
                        log: self.log,
                        global: self.global,
                    };
                    Some(filter.write(filter_context, content))
                },
                Action::SilentAbort => None,
                Action::Abort(e) => {
                    error = Some(e);
                    None
                }
            }).collect();

            match error {
                Some(e) => return Err(Error::Filter(e)),
                None => {
                    let filter_context = FilterContext {
                        storage: &mut self.filter_storage,
                        log: self.log,
                        global: self.global,
                    };
                    write_queue.push(filter.end(filter_context))
                }
            }
        }

        for action in write_queue {
            try!{
                match action {
                    Action::Next(Some(content)) => writer.write_all(content.as_bytes()),
                    Action::Abort(e) => return Err(Error::Filter(e)),
                    _ => Ok(())
                }
            }
        }

        writer.end().map_err(|e| Error::Io(e))
    }

    fn borrow_writer(&mut self) -> Result<&mut hyper::server::response::Response<'a, hyper::net::Streaming>, Error> {
        match self.writer {
            Some(Ok(ref mut writer)) => Ok(writer),
            None => Err(Error::Io(io::Error::new(io::ErrorKind::BrokenPipe, "write after close"))),
            Some(Err(_)) => if let Some(Err(e)) = self.writer.take() {
                Err(e)
            } else { unreachable!(); }
        }
    }
}

impl<'a, 'b> Write for ResponseWriter<'a, 'b> {
    fn write(&mut self, content: &[u8]) -> io::Result<usize> {
        response_to_io_result(self.try_send(content))
    }

    fn write_all(&mut self, content: &[u8]) -> io::Result<()> {
        self.write(content).map(|_| ())
    }

    fn flush(&mut self) -> io::Result<()> {
        let mut writer = try!(response_to_io_result(self.borrow_writer()));
        writer.flush()
    }
}

#[allow(unused_must_use)]
impl<'a, 'b> Drop for ResponseWriter<'a, 'b> {
    ///Finishes writing and closes the connection.
    fn drop(&mut self) {
        if self.writer.is_some() {
            self.finish();
        }
    }
}

fn response_to_io_result<T>(res:  Result<T, Error>) -> io::Result<T> {
    match res {
        Ok(v) => Ok(v),
        Err(Error::Io(e)) => Err(e),
        Err(e) => Err(io::Error::new(io::ErrorKind::Other, e))
    }
}<|endoftext|>


<commit_before>//! An augmentation of the rust-http Response struct.

use std::io::{IoResult, File, MemReader};
use std::io::util::copy;
use std::path::BytesContainer;

use http::status::{Status, InternalServerError};
use http::headers::response::HeaderCollection;

pub use HttpResponse = http::server::response::ResponseWriter;

use contenttype::get_content_type;

/// The response representation given to `Middleware`
pub struct Response<'a, 'b> {
    http_res: &'a mut HttpResponse<'b>,
    pub body: Box<Reader>,
    pub headers: Box<HeaderCollection>,
    pub status: Status
}

impl<'a, 'b> Response<'a, 'b> {
    /// Construct a Response from an HttpResponse reference
    pub fn from_http(http_res: &'a mut HttpResponse<'b>) -> Response<'a, 'b> {
        Response {
            headers: http_res.headers.clone(),
            status: http_res.status.clone(),
            http_res: http_res,
            body: box MemReader::new(vec![]) as Box<Reader>
        }
    }

    /// Write the `Status` and data to the `Response`.
    pub fn serve<S: BytesContainer>(&mut self, status: Status, body: S) {
        self.status = status;
        self.body = box MemReader::new(body.container_as_bytes().to_owned()) as Box<Reader>;
    }

    /// Serve the file located at `path`.
    ///
    /// This usually means a request has been handlded, and `Middleware`
    /// may want to `Unwind` after a file is served. If the status should be
    /// anything other than `200`, `Middleware` must set it, including in
    /// the case of an `Err`.
    ///
    /// `serve_file` will error if the file does not exist, the process
    /// does not have correct permissions, or it has other issues in reading
    /// from the file. `Middleware` should handle this gracefully.
    pub fn serve_file(&mut self, path: &Path) -> IoResult<()> {
        let file = try!(File::open(path));
        self.headers.content_type = path.extension_str().and_then(get_content_type);
        self.body = box file as Box<Reader>;
        Ok(())
    }

    /// Internal. Should not be called by the user.
    ///
    /// `write_back` is used to put all the data added to `self`
    /// back onto an `HttpResponse` so that it is sent back to the
    /// client.
    ///
    /// `write_back` consumes the `Response`.
    pub fn write_back(mut self) {
        self.http_res.headers = self.headers.clone();
        self.http_res.status = self.status.clone();
        let _ = match self.body.read_to_string() {
            Ok(body) => {
                self.http_res.write_content_auto(
                    match self.headers.content_type {
                        Some(ref ctype) => ctype.clone(),
                        None => get_content_type("txt").unwrap()
                    }, body)
            },
            Err(e) => Err(e)
        }.map_err(|e| {
            error!("Error reading/writing body: {}", e);
            self.http_res.status = InternalServerError;
            let _ = self.http_res.write(b"Internal Server Error")
                .map_err(|e| error!("Error writing error message: {}", e));
        });
    }
}

#[test]
fn matches_content_type () {
    let path = &Path::new("test.txt");
    let content_type = path.extension_str().and_then(get_content_type).unwrap();

    assert_eq!(content_type.type_.as_slice(), "text");
    assert_eq!(content_type.subtype.as_slice(), "plain");
}
<commit_msg>(doc) Documented Response wrapper fields.<commit_after>//! An augmentation of the rust-http Response struct.

use std::io::{IoResult, File, MemReader};
use std::path::BytesContainer;

use http::status::{Status, InternalServerError};
use http::headers::response::HeaderCollection;

pub use HttpResponse = http::server::response::ResponseWriter;

use contenttype::get_content_type;

/// The response representation given to `Middleware`
pub struct Response<'a, 'b> {
    http_res: &'a mut HttpResponse<'b>,

    /// The body of the response.
    ///
    /// This is a Reader for generality, most data should
    /// be sent using either `serve` or `serve_file`.
    ///
    /// Arbitrary Readers can be sent by assigning to body.
    pub body: Box<Reader>,

    /// The headers of the response.
    pub headers: Box<HeaderCollection>,

    /// The response status-code.
    pub status: Status
}

impl<'a, 'b> Response<'a, 'b> {
    /// Construct a Response from an HttpResponse reference
    pub fn from_http(http_res: &'a mut HttpResponse<'b>) -> Response<'a, 'b> {
        Response {
            headers: http_res.headers.clone(),
            status: http_res.status.clone(),
            http_res: http_res,
            body: box MemReader::new(vec![]) as Box<Reader>
        }
    }

    /// Write the `Status` and data to the `Response`.
    pub fn serve<S: BytesContainer>(&mut self, status: Status, body: S) {
        self.status = status;
        self.body = box MemReader::new(body.container_as_bytes().to_vec()) as Box<Reader>;
    }

    /// Serve the file located at `path`.
    ///
    /// This usually means a request has been handlded, and `Middleware`
    /// may want to `Unwind` after a file is served. If the status should be
    /// anything other than `200`, `Middleware` must set it, including in
    /// the case of an `Err`.
    ///
    /// `serve_file` will error if the file does not exist, the process
    /// does not have correct permissions, or it has other issues in reading
    /// from the file. `Middleware` should handle this gracefully.
    pub fn serve_file(&mut self, path: &Path) -> IoResult<()> {
        let file = try!(File::open(path));
        self.headers.content_type = path.extension_str().and_then(get_content_type);
        self.body = box file as Box<Reader>;
        Ok(())
    }

    /// Internal. Should not be called by the user.
    ///
    /// `write_back` is used to put all the data added to `self`
    /// back onto an `HttpResponse` so that it is sent back to the
    /// client.
    ///
    /// `write_back` consumes the `Response`.
    pub fn write_back(mut self) {
        self.http_res.headers = self.headers.clone();
        self.http_res.status = self.status.clone();
        let _ = match self.body.read_to_string() {
            Ok(body) => {
                self.http_res.write_content_auto(
                    match self.headers.content_type {
                        Some(ref ctype) => ctype.clone(),
                        None => get_content_type("txt").unwrap()
                    }, body)
            },
            Err(e) => Err(e)
        }.map_err(|e| {
            error!("Error reading/writing body: {}", e);
            self.http_res.status = InternalServerError;
            let _ = self.http_res.write(b"Internal Server Error")
                .map_err(|e| error!("Error writing error message: {}", e));
        });
    }
}

#[test]
fn matches_content_type () {
    let path = &Path::new("test.txt");
    let content_type = path.extension_str().and_then(get_content_type).unwrap();

    assert_eq!(content_type.type_.as_slice(), "text");
    assert_eq!(content_type.subtype.as_slice(), "plain");
}
<|endoftext|>


<commit_before>use crate::vector::VectorTarget;

#[repr(C)]
pub struct RustVec<T: VectorTarget<T>> {
    repr: Vec<T>,
}

impl<T: VectorTarget<T>> RustVec<T> {
    pub fn from(v: Vec<T>) -> Self {
        RustVec { repr: v }
    }

    pub fn from_ref(v: &Vec<T>) -> &Self {
        unsafe { std::mem::transmute::<&Vec<T>, &RustVec<T>>(v) }
    }

    pub fn into_vec(self) -> Vec<T> {
        self.repr
    }

    pub fn as_vec(&self) -> &Vec<T> {
        &self.repr
    }

    pub fn as_mut_vec(&mut self) -> &mut Vec<T> {
        &mut self.repr
    }

    pub fn len(&self) -> usize {
        self.repr.len()
    }
}
<commit_msg>Update RustVec::from_ref to match RustString::from_ref<commit_after>use crate::vector::VectorTarget;

#[repr(C)]
pub struct RustVec<T: VectorTarget<T>> {
    repr: Vec<T>,
}

impl<T: VectorTarget<T>> RustVec<T> {
    pub fn from(v: Vec<T>) -> Self {
        RustVec { repr: v }
    }

    pub fn from_ref(v: &Vec<T>) -> &Self {
        unsafe { &*(v as *const Vec<T> as *const RustVec<T>) }
    }

    pub fn into_vec(self) -> Vec<T> {
        self.repr
    }

    pub fn as_vec(&self) -> &Vec<T> {
        &self.repr
    }

    pub fn as_mut_vec(&mut self) -> &mut Vec<T> {
        &mut self.repr
    }

    pub fn len(&self) -> usize {
        self.repr.len()
    }
}
<|endoftext|>


<commit_before>use std::cmp;
use std::sync::{Arc, RwLock};
use std::sync::mpsc::{Receiver, Sender};

use line_storage::LineStorage;
use search::{Request, Response};

pub enum Input {
    Search(Request),
}

pub enum Reply {
    DidSearch(Response),
}

pub struct Searcher {
    line_storage: Arc<RwLock<LineStorage>>,
}

impl Searcher {
    pub fn new(line_storage: Arc<RwLock<LineStorage>>) -> Self {
        Searcher {
            line_storage: line_storage,
        }
    }

    pub fn start(self, input_rx: Receiver<Input>, reply_tx: Sender<Reply>) {
        loop {
            use self::Input::*;
            let reply = match input_rx.recv() {
                Ok(Search(request)) => self.search(request),
                Err(_) => return,
            };
            let _dont_care = reply_tx.send(reply).is_ok();
        }
    }

    fn search(&self, request: Request) -> Reply {
        let Request { query, start } = request;
        let tests_per_req = 5000;
        let mut line_indices = Vec::new();
        let line_storage = self.line_storage.read().unwrap();
        for (i, line) in line_storage.iter().enumerate().skip(start).take(tests_per_req) {
            if query.test(line.as_chars()) {
                line_indices.push(i);
            }
        }
        let end = cmp::min(start + tests_per_req, line_storage.len());
        let response = Response::new(query, line_indices, start..end);
        Reply::DidSearch(response)
    }
}
<commit_msg>Increase test_per_req rate<commit_after>use std::cmp;
use std::sync::{Arc, RwLock};
use std::sync::mpsc::{Receiver, Sender};

use line_storage::LineStorage;
use search::{Request, Response};

pub enum Input {
    Search(Request),
}

pub enum Reply {
    DidSearch(Response),
}

pub struct Searcher {
    line_storage: Arc<RwLock<LineStorage>>,
}

impl Searcher {
    pub fn new(line_storage: Arc<RwLock<LineStorage>>) -> Self {
        Searcher {
            line_storage: line_storage,
        }
    }

    pub fn start(self, input_rx: Receiver<Input>, reply_tx: Sender<Reply>) {
        loop {
            use self::Input::*;
            let reply = match input_rx.recv() {
                Ok(Search(request)) => self.search(request),
                Err(_) => return,
            };
            let _dont_care = reply_tx.send(reply).is_ok();
        }
    }

    fn search(&self, request: Request) -> Reply {
        let Request { query, start } = request;
        let tests_per_req = 500_000;
        let mut line_indices = Vec::new();
        let line_storage = self.line_storage.read().unwrap();
        for (i, line) in line_storage.iter().enumerate().skip(start).take(tests_per_req) {
            if query.test(line.as_chars()) {
                line_indices.push(i);
            }
        }
        let end = cmp::min(start + tests_per_req, line_storage.len());
        let response = Response::new(query, line_indices, start..end);
        Reply::DidSearch(response)
    }
}
<|endoftext|>


<commit_before>use std::io::{Result, SeekFrom, Seek, Read};
use std::fs::{File};
use std::path::Path;
use std::str::{from_utf8};
use byteorder::{LittleEndian, ReadBytesExt};

pub enum Flags {
    BackgroundFlag =    0x00000001,
    WeaponFlag =        0x00000002,
    TransparentFlag =   0x00000004,
    TranslucentFlag =   0x00000008,
    WallFlag =          0x00000010,
    DamagingFlag =      0x00000020,
    ImpassableFlag =    0x00000040,
    WetFlag =           0x00000080,
    UnknownFlag =       0x00000100,
    SurfaceFlag =       0x00000200,
    BridgeFlag =        0x00000400,
    StackableFlag =     0x00000800,
    WindowFlag =        0x00001000,
    NoShootFlag =       0x00002000,
    PrefixAFlag =       0x00004000,
    PrefixAnFlag =      0x00008000,
    InternalFlag =      0x00010000,
    FoliageFlag =       0x00020000,
    PartialHueFlag =    0x00040000,
    Unknown1Flag =      0x00080000,
    MapFlag =           0x00100000,
    ContainerFlag =     0x00200000,
    WearableFlag =      0x00400000,
    LightSourceFlag =   0x00800000,
    AnimatedFlag =      0x01000000,
    NoDiagonalFlag =    0x02000000,
    Unknown2Flag =      0x04000000,
    ArmorFlag =         0x08000000,
    RoofFlag =          0x10000000,
    DoorFlag =          0x20000000,
    StairBackFlag =     0x40000000,
    StairRightFlag =    0x80000000
}

// Tile data is odd, as we have [(unknown, (LAND_TILE_DATA) *32) * 512]
static GROUP_HEADER_SIZE:u32 = 4;
static MAP_TILE_SIZE:u32 = 26;
static STATIC_TILE_SIZE:u32 = 37;
static STATIC_OFFSET:u32 = 428032;

pub struct MapTileData {
    pub flags: u32,
    pub texture_id: u16,
    pub name: String
}

pub struct StaticTileData {
    pub flags: u32,
    pub weight: u8,
    pub quality_layer_light_id: u8,
    pub quantity_weapon_class_armor_class: u8,
    pub anim_id: u16,
    pub hue: u8,
    pub height_capacity: u8,
    pub name: String
}

pub struct TileDataReader {
    data_reader: File  //FIXME: This should be a Read + Seek instead of File
}

impl TileDataReader {
    pub fn new(mul_path: &Path) -> Result<TileDataReader> {
        let data_reader = try!(File::open(mul_path));

        Ok(TileDataReader {
            data_reader: data_reader
        })
    }

    pub fn read_map_tile_data(&mut self, idx: u32) -> Result<MapTileData> {
        let offset = self.calculate_map_tile_offset(idx);
        try!(self.data_reader.seek(SeekFrom::Start(offset)));
        let flags = try!(self.data_reader.read_u32::<LittleEndian>());
        let texture_id = try!(self.data_reader.read_u16::<LittleEndian>());
        let reader = &self.data_reader;

        let raw_name = try!(reader.bytes().take_while(|ref c| match *c {
            &Ok(n)  => n != 0,
            &Err(_) => true,
        }).collect::<Result<Vec<u8>>>());

        Ok(MapTileData {
            flags: flags,
            texture_id: texture_id,
            name: String::from(from_utf8(&raw_name).unwrap())
        })
    }

    fn calculate_map_tile_offset(&self, idx: u32) -> u64 {
        //For every 32, we have to add an unknown header
        let group_header_jumps = ((idx / 32) + 1) * GROUP_HEADER_SIZE;
        ((idx * MAP_TILE_SIZE) + group_header_jumps) as u64
    }

    pub fn read_static_tile_data(&mut self, idx: u32) -> Result<StaticTileData> {
        let offset = self.calculate_static_tile_offset(idx);
        try!(self.data_reader.seek(SeekFrom::Start(offset)));

        let flags = try!(self.data_reader.read_u32::<LittleEndian>());
        let weight = try!(self.data_reader.read_u8());
        let quality = try!(self.data_reader.read_u8());
        let _unknown = try!(self.data_reader.read_u16::<LittleEndian>());
        let _unknown1 = try!(self.data_reader.read_u8());
        let quantity = try!(self.data_reader.read_u8());
        let anim_id = try!(self.data_reader.read_u16::<LittleEndian>());
        let _unknown2 = try!(self.data_reader.read_u8());
        let hue = try!(self.data_reader.read_u8());
        let _unknown3 = try!(self.data_reader.read_u16::<LittleEndian>());
        let height = try!(self.data_reader.read_u8());

        let reader = &self.data_reader;
        let raw_name = try!(reader.bytes().take_while(|ref c| match *c {
            &Ok(n)  => n != 0,
            &Err(_) => true,
        }).collect::<Result<Vec<u8>>>());

        Ok(StaticTileData {
            flags: flags,
            weight: weight,
            quality_layer_light_id: quality,
            quantity_weapon_class_armor_class: quantity,
            anim_id: anim_id,
            hue: hue,
            height_capacity: height,
            name: String::from(from_utf8(&raw_name).unwrap())
        })
    }

    fn calculate_static_tile_offset(&self, idx: u32) -> u64 {
        //For every 32, we have to add an unknown header
        let group_header_jumps = ((idx / 32) + 1) * GROUP_HEADER_SIZE;
        ((idx * STATIC_TILE_SIZE) + group_header_jumps + STATIC_OFFSET) as u64
    }
}
<commit_msg>Made types cloneable<commit_after>use std::io::{Result, SeekFrom, Seek, Read};
use std::fs::{File};
use std::path::Path;
use std::str::{from_utf8};
use byteorder::{LittleEndian, ReadBytesExt};

pub enum Flags {
    BackgroundFlag =    0x00000001,
    WeaponFlag =        0x00000002,
    TransparentFlag =   0x00000004,
    TranslucentFlag =   0x00000008,
    WallFlag =          0x00000010,
    DamagingFlag =      0x00000020,
    ImpassableFlag =    0x00000040,
    WetFlag =           0x00000080,
    UnknownFlag =       0x00000100,
    SurfaceFlag =       0x00000200,
    BridgeFlag =        0x00000400,
    StackableFlag =     0x00000800,
    WindowFlag =        0x00001000,
    NoShootFlag =       0x00002000,
    PrefixAFlag =       0x00004000,
    PrefixAnFlag =      0x00008000,
    InternalFlag =      0x00010000,
    FoliageFlag =       0x00020000,
    PartialHueFlag =    0x00040000,
    Unknown1Flag =      0x00080000,
    MapFlag =           0x00100000,
    ContainerFlag =     0x00200000,
    WearableFlag =      0x00400000,
    LightSourceFlag =   0x00800000,
    AnimatedFlag =      0x01000000,
    NoDiagonalFlag =    0x02000000,
    Unknown2Flag =      0x04000000,
    ArmorFlag =         0x08000000,
    RoofFlag =          0x10000000,
    DoorFlag =          0x20000000,
    StairBackFlag =     0x40000000,
    StairRightFlag =    0x80000000
}

// Tile data is odd, as we have [(unknown, (LAND_TILE_DATA) *32) * 512]
static GROUP_HEADER_SIZE:u32 = 4;
static MAP_TILE_SIZE:u32 = 26;
static STATIC_TILE_SIZE:u32 = 37;
static STATIC_OFFSET:u32 = 428032;

#[derive(Clone)]
pub struct MapTileData {
    pub flags: u32,
    pub texture_id: u16,
    pub name: String
}

#[derive(Clone)]
pub struct StaticTileData {
    pub flags: u32,
    pub weight: u8,
    pub quality_layer_light_id: u8,
    pub quantity_weapon_class_armor_class: u8,
    pub anim_id: u16,
    pub hue: u8,
    pub height_capacity: u8,
    pub name: String
}

pub struct TileDataReader {
    data_reader: File  //FIXME: This should be a Read + Seek instead of File
}

impl TileDataReader {
    pub fn new(mul_path: &Path) -> Result<TileDataReader> {
        let data_reader = File::open(mul_path)?;

        Ok(TileDataReader {
            data_reader: data_reader
        })
    }

    pub fn read_map_tile_data(&mut self, idx: u32) -> Result<MapTileData> {
        let offset = self.calculate_map_tile_offset(idx);
        self.data_reader.seek(SeekFrom::Start(offset))?;
        let flags = self.data_reader.read_u32::<LittleEndian>()?;
        let texture_id = self.data_reader.read_u16::<LittleEndian>()?;
        let reader = &self.data_reader;

        let raw_name = reader.bytes().take_while(|ref c| match *c {
            &Ok(n)  => n != 0,
            &Err(_) => true,
        }).collect::<Result<Vec<u8>>>()?;

        Ok(MapTileData {
            flags: flags,
            texture_id: texture_id,
            name: String::from(from_utf8(&raw_name).unwrap())
        })
    }

    fn calculate_map_tile_offset(&self, idx: u32) -> u64 {
        //For every 32, we have to add an unknown header
        let group_header_jumps = ((idx / 32) + 1) * GROUP_HEADER_SIZE;
        ((idx * MAP_TILE_SIZE) + group_header_jumps) as u64
    }

    pub fn read_static_tile_data(&mut self, idx: u32) -> Result<StaticTileData> {
        let offset = self.calculate_static_tile_offset(idx);
        self.data_reader.seek(SeekFrom::Start(offset))?;

        let flags = self.data_reader.read_u32::<LittleEndian>()?;
        let weight = self.data_reader.read_u8()?;
        let quality = self.data_reader.read_u8()?;
        let _unknown = self.data_reader.read_u16::<LittleEndian>()?;
        let _unknown1 = self.data_reader.read_u8()?;
        let quantity = self.data_reader.read_u8()?;
        let anim_id = self.data_reader.read_u16::<LittleEndian>()?;
        let _unknown2 = self.data_reader.read_u8()?;
        let hue = self.data_reader.read_u8()?;
        let _unknown3 = self.data_reader.read_u16::<LittleEndian>()?;
        let height = self.data_reader.read_u8()?;

        let reader = &self.data_reader;
        let raw_name = reader.bytes().take_while(|ref c| match *c {
            &Ok(n)  => n != 0,
            &Err(_) => true,
        }).collect::<Result<Vec<u8>>>()?;

        Ok(StaticTileData {
            flags: flags,
            weight: weight,
            quality_layer_light_id: quality,
            quantity_weapon_class_armor_class: quantity,
            anim_id: anim_id,
            hue: hue,
            height_capacity: height,
            name: String::from(from_utf8(&raw_name).unwrap())
        })
    }

    fn calculate_static_tile_offset(&self, idx: u32) -> u64 {
        //For every 32, we have to add an unknown header
        let group_header_jumps = ((idx / 32) + 1) * GROUP_HEADER_SIZE;
        ((idx * STATIC_TILE_SIZE) + group_header_jumps + STATIC_OFFSET) as u64
    }
}
<|endoftext|>