<commit_before>use libc;

use std::any::Any;
use std::io;
use std::os::unix::io::{AsRawFd, RawFd};
use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};

static REDIRECT_FLAGS: [AtomicBool; 3] = [ATOMIC_BOOL_INIT, ATOMIC_BOOL_INIT, ATOMIC_BOOL_INIT];

pub struct RedirectError<F> {
    pub error: io::Error,
    pub file: F,
}

impl<F> From<RedirectError<F>> for io::Error {
    fn from(err: RedirectError<F>) -> io::Error {
        err.error
    }
}

impl<F: Any> ::std::error::Error for RedirectError<F> {
    fn description(&self) -> &str {
        self.error.description()
    }
    fn cause(&self) -> Option<&::std::error::Error> {
        Some(&self.error)
    }
}

impl<F> ::std::fmt::Display for RedirectError<F> {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
        self.error.fmt(fmt)
    }
}

impl<F> ::std::fmt::Debug for RedirectError<F> {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
        self.error.fmt(fmt)
    }
}

/// Redirect stderr/stdout to a file.
pub struct Redirect<F> {
    #[allow(dead_code)]
    fds: RedirectFds,
    file: F,
}

// Separate struct so we can destruct the redirect and drop the file descriptors.
struct RedirectFds {
    std_fd: RawFd,
    std_fd_dup: RawFd,
}

impl RedirectFds {
    fn make(std_fd: RawFd, file_fd: RawFd) -> io::Result<RedirectFds> {
        let std_fd_dup = unsafe { libc::dup(std_fd) };
        if std_fd_dup < 0 {
            return Err(io::Error::last_os_error());
        }

        // If this ends up panicing, something is seriously wrong. Regardless, we will only end up
        // leaking a single file descriptor so it's not the end of the world.
        if REDIRECT_FLAGS[std_fd as usize].fetch_or(true, Ordering::Relaxed) {
            unsafe {
                libc::close(std_fd_dup);
            }
            return Err(io::Error::new(
                io::ErrorKind::AlreadyExists,
                "Redirect already exists.",
            ));
        }

        // Dropping this will close std_fd_dup
        let fds = RedirectFds { std_fd, std_fd_dup };

        match unsafe { libc::dup2(file_fd, std_fd) } {
            // Drop is still correct even if this doesn't succeed.
            -1 => Err(io::Error::last_os_error()),
            _ => Ok(fds),
        }
    }
}

impl Drop for RedirectFds {
    fn drop(&mut self) {
        unsafe {
            // Check for errors?
            libc::dup2(self.std_fd_dup, self.std_fd);
            libc::close(self.std_fd_dup);
            REDIRECT_FLAGS[self.std_fd as usize].store(false, Ordering::Relaxed);
        }
    }
}

impl<F> Redirect<F>
where
    F: AsRawFd,
{
    fn make(std_fd: RawFd, file: F) -> Result<Self, RedirectError<F>> {
        let fds = match RedirectFds::make(std_fd, file.as_raw_fd()) {
            Ok(fds) => fds,
            Err(error) => return Err(RedirectError { error, file }),
        };
        Ok(Redirect { fds, file })
    }
    /// Redirect stdout to `file`.
    pub fn stdout(file: F) -> Result<Self, RedirectError<F>> {
        Redirect::make(libc::STDOUT_FILENO, file)
    }
    /// Redirect stderr to `file`.
    pub fn stderr(file: F) -> Result<Self, RedirectError<F>> {
        Redirect::make(libc::STDERR_FILENO, file)
    }

    /// Extract inner file object.
    pub fn into_inner(self) -> F {
        self.file
    }
}
<commit_msg>fix atomic bool warning<commit_after>use libc;

use std::any::Any;
use std::io;
use std::os::unix::io::{AsRawFd, RawFd};
use std::sync::atomic::{AtomicBool, Ordering};

static REDIRECT_FLAGS: [AtomicBool; 3] = [
    AtomicBool::new(false),
    AtomicBool::new(false),
    AtomicBool::new(false),
];

pub struct RedirectError<F> {
    pub error: io::Error,
    pub file: F,
}

impl<F> From<RedirectError<F>> for io::Error {
    fn from(err: RedirectError<F>) -> io::Error {
        err.error
    }
}

impl<F: Any> ::std::error::Error for RedirectError<F> {
    fn description(&self) -> &str {
        self.error.description()
    }
    fn cause(&self) -> Option<&::std::error::Error> {
        Some(&self.error)
    }
}

impl<F> ::std::fmt::Display for RedirectError<F> {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
        self.error.fmt(fmt)
    }
}

impl<F> ::std::fmt::Debug for RedirectError<F> {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
        self.error.fmt(fmt)
    }
}

/// Redirect stderr/stdout to a file.
pub struct Redirect<F> {
    #[allow(dead_code)]
    fds: RedirectFds,
    file: F,
}

// Separate struct so we can destruct the redirect and drop the file descriptors.
struct RedirectFds {
    std_fd: RawFd,
    std_fd_dup: RawFd,
}

impl RedirectFds {
    fn make(std_fd: RawFd, file_fd: RawFd) -> io::Result<RedirectFds> {
        let std_fd_dup = unsafe { libc::dup(std_fd) };
        if std_fd_dup < 0 {
            return Err(io::Error::last_os_error());
        }

        // If this ends up panicing, something is seriously wrong. Regardless, we will only end up
        // leaking a single file descriptor so it's not the end of the world.
        if REDIRECT_FLAGS[std_fd as usize].fetch_or(true, Ordering::Relaxed) {
            unsafe {
                libc::close(std_fd_dup);
            }
            return Err(io::Error::new(
                io::ErrorKind::AlreadyExists,
                "Redirect already exists.",
            ));
        }

        // Dropping this will close std_fd_dup
        let fds = RedirectFds { std_fd, std_fd_dup };

        match unsafe { libc::dup2(file_fd, std_fd) } {
            // Drop is still correct even if this doesn't succeed.
            -1 => Err(io::Error::last_os_error()),
            _ => Ok(fds),
        }
    }
}

impl Drop for RedirectFds {
    fn drop(&mut self) {
        unsafe {
            // Check for errors?
            libc::dup2(self.std_fd_dup, self.std_fd);
            libc::close(self.std_fd_dup);
            REDIRECT_FLAGS[self.std_fd as usize].store(false, Ordering::Relaxed);
        }
    }
}

impl<F> Redirect<F>
where
    F: AsRawFd,
{
    fn make(std_fd: RawFd, file: F) -> Result<Self, RedirectError<F>> {
        let fds = match RedirectFds::make(std_fd, file.as_raw_fd()) {
            Ok(fds) => fds,
            Err(error) => return Err(RedirectError { error, file }),
        };
        Ok(Redirect { fds, file })
    }
    /// Redirect stdout to `file`.
    pub fn stdout(file: F) -> Result<Self, RedirectError<F>> {
        Redirect::make(libc::STDOUT_FILENO, file)
    }
    /// Redirect stderr to `file`.
    pub fn stderr(file: F) -> Result<Self, RedirectError<F>> {
        Redirect::make(libc::STDERR_FILENO, file)
    }

    /// Extract inner file object.
    pub fn into_inner(self) -> F {
        self.file
    }
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;
use std::collections::HashMap;

use actix::Actor;
use http::Method;
use futures::Stream;

use task::Task;
use error::{Result, Error};
use route::{Route, RouteHandler, RouteResult, Frame, FnHandler, StreamHandler};
use context::HttpContext;
use httprequest::HttpRequest;
use httpresponse::HttpResponse;
use httpcodes::{HTTPNotFound, HTTPMethodNotAllowed};

/// Http resource
///
/// `Resource` is an entry in route table which corresponds to requested URL.
///
/// Resource in turn has at least one route.
/// Route corresponds to handling HTTP method by calling route handler.
///
/// ```rust,ignore
///
/// struct MyRoute;
///
/// fn main() {
///     let router = RoutingMap::default()
///         .resource("/", |r| r.post::<MyRoute>())
///         .finish();
/// }
pub struct Resource<S=()> {
    name: String,
    state: PhantomData<S>,
    routes: HashMap<Method, Box<RouteHandler<S>>>,
    default: Box<RouteHandler<S>>,
}

impl<S> Default for Resource<S> {
    fn default() -> Self {
        Resource {
            name: String::new(),
            state: PhantomData,
            routes: HashMap::new(),
            default: Box::new(HTTPMethodNotAllowed)}
    }
}

impl<S> Resource<S> where S: 'static {

    pub(crate) fn default_not_found() -> Self {
        Resource {
            name: String::new(),
            state: PhantomData,
            routes: HashMap::new(),
            default: Box::new(HTTPNotFound)}
    }

    /// Set resource name
    pub fn set_name<T: Into<String>>(&mut self, name: T) {
        self.name = name.into();
    }

    /// Register handler for specified method.
    pub fn handler<F, R>(&mut self, method: Method, handler: F)
        where F: Fn(HttpRequest<S>) -> Result<R> + 'static,
              R: Into<HttpResponse> + 'static,
    {
        self.routes.insert(method, Box::new(FnHandler::new(handler)));
    }

    /// Register async handler for specified method.
    pub fn async<F, R>(&mut self, method: Method, handler: F)
        where F: Fn(HttpRequest<S>) -> R + 'static,
              R: Stream<Item=Frame, Error=Error> + 'static,
    {
        self.routes.insert(method, Box::new(StreamHandler::new(handler)));
    }

    /// Register handler for specified method.
    pub fn route_handler<H>(&mut self, method: Method, handler: H)
        where H: RouteHandler<S>
    {
        self.routes.insert(method, Box::new(handler));
    }

    /// Default handler is used if no matched route found.
    /// By default `HTTPMethodNotAllowed` is used.
    pub fn default_handler<H>(&mut self, handler: H)
        where H: RouteHandler<S>
    {
        self.default = Box::new(handler);
    }

    /// Handler for `GET` method.
    pub fn get<A>(&mut self)
        where A: Actor<Context=HttpContext<A>> + Route<State=S>
    {
        self.route_handler(Method::GET, A::factory());
    }

    /// Handler for `POST` method.
    pub fn post<A>(&mut self)
        where A: Actor<Context=HttpContext<A>> + Route<State=S>
    {
        self.route_handler(Method::POST, A::factory());
    }

    /// Handler for `PUR` method.
    pub fn put<A>(&mut self)
        where A: Actor<Context=HttpContext<A>> + Route<State=S>
    {
        self.route_handler(Method::PUT, A::factory());
    }

    /// Handler for `METHOD` method.
    pub fn delete<A>(&mut self)
        where A: Actor<Context=HttpContext<A>> + Route<State=S>
    {
        self.route_handler(Method::DELETE, A::factory());
    }
}

impl<S: 'static> RouteHandler<S> for Resource<S> {

    fn handle(&self, req: HttpRequest<S>) -> Task {
        if let Some(handler) = self.routes.get(req.method()) {
            handler.handle(req)
        } else {
            self.default.handle(req)
        }
    }
}

#[cfg_attr(feature="cargo-clippy", allow(large_enum_variant))]
enum ReplyItem<A> where A: Actor + Route {
    Message(HttpResponse),
    Actor(A),
}

/// Represents response process.
pub struct Reply<A: Actor + Route> (ReplyItem<A>);

impl<A> Reply<A> where A: Actor + Route
{
    /// Create async response
    pub fn async(act: A) -> RouteResult<A> {
        Ok(Reply(ReplyItem::Actor(act)))
    }

    /// Send response
    pub fn reply<R: Into<HttpResponse>>(response: R) -> RouteResult<A> {
        Ok(Reply(ReplyItem::Message(response.into())))
    }

    pub fn into(self, mut ctx: HttpContext<A>) -> Task where A: Actor<Context=HttpContext<A>>
    {
        match self.0 {
            ReplyItem::Message(msg) => {
                Task::reply(msg)
            },
            ReplyItem::Actor(act) => {
                ctx.set_actor(act);
                Task::with_context(ctx)
            }
        }
    }
}

impl<A, T> From<T> for Reply<A>
    where T: Into<HttpResponse>, A: Actor + Route
{
    fn from(item: T) -> Self {
        Reply(ReplyItem::Message(item.into()))
    }
}
<commit_msg>make resource handler result more generic<commit_after>use std::marker::PhantomData;
use std::collections::HashMap;

use actix::Actor;
use http::Method;
use futures::Stream;

use task::Task;
use error::Error;
use route::{Route, RouteHandler, RouteResult, Frame, FnHandler, StreamHandler};
use context::HttpContext;
use httprequest::HttpRequest;
use httpresponse::HttpResponse;
use httpcodes::{HTTPNotFound, HTTPMethodNotAllowed};

/// Http resource
///
/// `Resource` is an entry in route table which corresponds to requested URL.
///
/// Resource in turn has at least one route.
/// Route corresponds to handling HTTP method by calling route handler.
///
/// ```rust,ignore
///
/// struct MyRoute;
///
/// fn main() {
///     let router = RoutingMap::default()
///         .resource("/", |r| r.post::<MyRoute>())
///         .finish();
/// }
pub struct Resource<S=()> {
    name: String,
    state: PhantomData<S>,
    routes: HashMap<Method, Box<RouteHandler<S>>>,
    default: Box<RouteHandler<S>>,
}

impl<S> Default for Resource<S> {
    fn default() -> Self {
        Resource {
            name: String::new(),
            state: PhantomData,
            routes: HashMap::new(),
            default: Box::new(HTTPMethodNotAllowed)}
    }
}

impl<S> Resource<S> where S: 'static {

    pub(crate) fn default_not_found() -> Self {
        Resource {
            name: String::new(),
            state: PhantomData,
            routes: HashMap::new(),
            default: Box::new(HTTPNotFound)}
    }

    /// Set resource name
    pub fn set_name<T: Into<String>>(&mut self, name: T) {
        self.name = name.into();
    }

    /// Register handler for specified method.
    pub fn handler<F, R>(&mut self, method: Method, handler: F)
        where F: Fn(HttpRequest<S>) -> R + 'static,
              R: Into<HttpResponse> + 'static,
    {
        self.routes.insert(method, Box::new(FnHandler::new(handler)));
    }

    /// Register async handler for specified method.
    pub fn async<F, R>(&mut self, method: Method, handler: F)
        where F: Fn(HttpRequest<S>) -> R + 'static,
              R: Stream<Item=Frame, Error=Error> + 'static,
    {
        self.routes.insert(method, Box::new(StreamHandler::new(handler)));
    }

    /// Register handler for specified method.
    pub fn route_handler<H>(&mut self, method: Method, handler: H)
        where H: RouteHandler<S>
    {
        self.routes.insert(method, Box::new(handler));
    }

    /// Default handler is used if no matched route found.
    /// By default `HTTPMethodNotAllowed` is used.
    pub fn default_handler<H>(&mut self, handler: H)
        where H: RouteHandler<S>
    {
        self.default = Box::new(handler);
    }

    /// Handler for `GET` method.
    pub fn get<A>(&mut self)
        where A: Actor<Context=HttpContext<A>> + Route<State=S>
    {
        self.route_handler(Method::GET, A::factory());
    }

    /// Handler for `POST` method.
    pub fn post<A>(&mut self)
        where A: Actor<Context=HttpContext<A>> + Route<State=S>
    {
        self.route_handler(Method::POST, A::factory());
    }

    /// Handler for `PUR` method.
    pub fn put<A>(&mut self)
        where A: Actor<Context=HttpContext<A>> + Route<State=S>
    {
        self.route_handler(Method::PUT, A::factory());
    }

    /// Handler for `METHOD` method.
    pub fn delete<A>(&mut self)
        where A: Actor<Context=HttpContext<A>> + Route<State=S>
    {
        self.route_handler(Method::DELETE, A::factory());
    }
}

impl<S: 'static> RouteHandler<S> for Resource<S> {

    fn handle(&self, req: HttpRequest<S>) -> Task {
        if let Some(handler) = self.routes.get(req.method()) {
            handler.handle(req)
        } else {
            self.default.handle(req)
        }
    }
}

#[cfg_attr(feature="cargo-clippy", allow(large_enum_variant))]
enum ReplyItem<A> where A: Actor + Route {
    Message(HttpResponse),
    Actor(A),
}

/// Represents response process.
pub struct Reply<A: Actor + Route> (ReplyItem<A>);

impl<A> Reply<A> where A: Actor + Route
{
    /// Create async response
    pub fn async(act: A) -> RouteResult<A> {
        Ok(Reply(ReplyItem::Actor(act)))
    }

    /// Send response
    pub fn reply<R: Into<HttpResponse>>(response: R) -> RouteResult<A> {
        Ok(Reply(ReplyItem::Message(response.into())))
    }

    pub fn into(self, mut ctx: HttpContext<A>) -> Task where A: Actor<Context=HttpContext<A>>
    {
        match self.0 {
            ReplyItem::Message(msg) => {
                Task::reply(msg)
            },
            ReplyItem::Actor(act) => {
                ctx.set_actor(act);
                Task::with_context(ctx)
            }
        }
    }
}

impl<A, T> From<T> for Reply<A>
    where T: Into<HttpResponse>, A: Actor + Route
{
    fn from(item: T) -> Self {
        Reply(ReplyItem::Message(item.into()))
    }
}
<|endoftext|>


<commit_before>use hyper::header::{CookiePair as Cookie, ContentLength, ContentType, Header, Location, SetCookie};
use hyper::status::StatusCode as Status;

use hyper::{Control, Headers, Next};

use hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value};

use handlebars::Handlebars;
use serde::ser::Serialize as ToJson;

pub use serde_json::value as value;

use std::fmt::Debug;
use std::borrow::Cow;
use std::io::{ErrorKind, Read, Result, Write};
use std::fs::{File, read_dir};
use std::path::Path;

use std::cell::RefCell;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};

use buffer::Buffer;

#[derive(Debug)]
pub struct Resp {
    status: RefCell<Status>,
    headers: RefCell<Headers>,
    body: RefCell<Buffer>,

    notify: AtomicBool,
    ctrl: Control
}

// no worries, the resp is always modified by only one thread at a time
unsafe impl Sync for Resp {}

impl Resp {
    pub fn new(ctrl: Control) -> Resp {
        Resp {
            status: RefCell::new(Status::Ok),
            headers: RefCell::new(Headers::default()),
            body: RefCell::new(Buffer::new()),

            notify: AtomicBool::new(false),
            ctrl: ctrl
        }
    }

    fn status(&self, status: Status) {
        *self.status.borrow_mut() = status;
    }

    fn has_header<H: Header>(&self) -> bool {
        self.headers.borrow().has::<H>()
    }

    fn header<H: Header>(&self, header: H) {
        self.headers.borrow_mut().set(header);
    }

    fn header_raw<K: Into<Cow<'static, str>> + Debug>(&self, name: K, value: Vec<Vec<u8>>) {
        self.headers.borrow_mut().set_raw(name, value);
    }

    fn push_cookie(&self, cookie: Cookie) {
        self.headers.borrow_mut().get_mut::<SetCookie>().unwrap().push(cookie)
    }

    fn len(&self) -> usize {
        self.body.borrow().len()
    }

    fn append<D: AsRef<[u8]>>(&self, content: D) {
        self.body.borrow_mut().append(content.as_ref());
    }

    fn send<D: Into<Vec<u8>>>(&self, content: D) {
        self.body.borrow_mut().send(content);
    }

    pub fn deconstruct(self) -> (Status, Headers, Buffer) {
        (self.status.into_inner(),
        self.headers.into_inner(),
        self.body.into_inner())
    }

    fn done(&self) {
        if self.notify.load(Ordering::Acquire) {
            self.ctrl.ready(Next::write()).unwrap();
        }
    }
}

pub fn set_notify(resp: &Option<Arc<Resp>>) {
    if let Some(ref arc) = *resp {
        arc.notify.store(true, Ordering::Release);
    }
}

/// This represents the response that will be sent back to the application.
///
/// Includes a status code (default 200 OK), headers, and a body.
/// The response can be updated and sent back immediately in a synchronous way,
/// or deferred pending some computation (asynchronous mode).
///
/// The response is sent when it is dropped.
pub struct Response {
    resp: Option<Arc<Resp>>
}

impl Drop for Response {
    fn drop(&mut self) {
        // this is to make sure that we remove this Response's strong reference to Resp
        // *before* we notify the handler, so the call to Arc::get_mut succeeds
        let resp = self.resp.as_ref().unwrap().as_ref() as *const Resp;

        // drop Arc
        {
            self.resp.take().unwrap();
        }

        // no worries: Resp is not dropped when the Arc is dropped,
        // because the handler outlives us, therefore the pointer is always valid here.
        unsafe {
            (*resp).done();
        }
    }
}

fn register_partials(handlebars: &mut Handlebars) -> Result<()> {
    for it in try!(read_dir("views/partials")) {
        let entry = try!(it);
        let path = entry.path();
        if path.extension().is_some() && path.extension().unwrap() == "hbs" {
            let name = path.file_stem().unwrap().to_str().unwrap();
            handlebars.register_template_file(name, path.as_path()).unwrap();
        }
    }
    Ok(())
}

pub fn new(resp: &Option<Arc<Resp>>) -> Response {
    Response {
        resp: Some(resp.as_ref().unwrap().clone())
    }
}

impl Response {

    fn resp(&self) -> &Resp {
        &self.resp.as_ref().unwrap()
    }

    /// Sets the status code of this response.
    pub fn status(&mut self, status: Status) -> &mut Self {
        self.resp().status(status);
        self
    }

    /// Sets the Content-Type header.
    pub fn content_type<S: Into<Vec<u8>>>(&mut self, mime: S) -> &mut Self {
        self.header_raw("Content-Type", mime)
    }

    /// Sets the Content-Length header.
    pub fn len(&mut self, len: u64) -> &mut Self {
        self.header(ContentLength(len))
    }

    /// Sets the Location header.
    pub fn location<S: Into<String>>(&mut self, url: S) -> &mut Self {
        self.header(Location(url.into()))
    }

    /// Redirects to the given URL with the given status, or 302 Found if none is given.
    pub fn redirect(mut self, url: &str, status: Option<Status>) {
        self.location(url);
        self.end(status.unwrap_or(Status::Found))
    }

    /// Sets the given header.
    pub fn header<H: Header>(&mut self, header: H) -> &mut Self {
        self.resp().header(header);
        self
    }

    /// Sets the given header with raw strings.
    pub fn header_raw<K: Into<Cow<'static, str>> + Debug, V: Into<Vec<u8>>>(&mut self, name: K, value: V) -> &mut Self {
        self.resp().header_raw(name, vec![value.into()]);
        self
    }

    /// Ends this response with the given status and an empty body
    pub fn end(mut self, status: Status) {
        self.status(status);
        self.len(0);
    }

    /// Renders the template at the given path using the given data.
    pub fn render<P: AsRef<Path>, T: ToJson>(self, path: P, data: T) {
        let mut handlebars = Handlebars::new();
        let path = path.as_ref();
        let name = path.file_stem().unwrap().to_str().unwrap();

        handlebars.register_template_file(name, path).unwrap();
        register_partials(&mut handlebars).unwrap();
        let result = handlebars.render(name, &data);
        self.send(result.unwrap())
    }

    /// Sends the given content and ends this response.
    /// Status defaults to 200 Ok, headers must have been set before this method is called.
    pub fn send<D: Into<Vec<u8>>>(mut self, content: D) {
        self.resp().send(content);
        let length = self.resp().len();
        self.len(length as u64);
    }

    /// Sends the given content and ends this response.
    /// Status defaults to 200 Ok, headers must have been set before this method is called.
    pub fn append<D: AsRef<[u8]>>(&mut self, content: D) {
        self.resp().append(content);
        let length = self.resp().len() as u64;
        self.len(length);
    }

    /// Sends the given file, setting the Content-Type based on the file's extension.
    /// Known extensions are htm, html, jpg, jpeg, png, js, css.
    /// If the file does not exist, this method sends a 404 Not Found response.
    pub fn send_file<P: AsRef<Path>>(mut self, path: P) {
        if !self.resp().has_header::<ContentType>() {
            let extension = path.as_ref().extension();
            if let Some(ext) = extension {
                let content_type = match ext.to_string_lossy().as_ref() {
                    "htm" | "html" => Some(ContentType::html()),
                    "jpg" | "jpeg" => Some(ContentType::jpeg()),
                    "png" => Some(ContentType::png()),
                    "js" => Some(ContentType(Mime(TopLevel::Text, SubLevel::Javascript, vec![(Attr::Charset, Value::Utf8)]))),
                    "css" => Some(ContentType(Mime(TopLevel::Text, SubLevel::Css, vec![(Attr::Charset, Value::Utf8)]))),
                    _ => None
                };

                if let Some(content_type) = content_type {
                    self.resp().header(content_type);
                }
            }
        }

        // read the whole file at once and send it
        // probably not the best idea for big files, we should use stream instead in that case
        match File::open(path) {
            Ok(mut file) => {
                let mut buf = Vec::with_capacity(file.metadata().ok().map_or(1024, |meta| meta.len() as usize));
                if let Err(err) = file.read_to_end(&mut buf) {
                    self.status(Status::InternalServerError).content_type("text/plain");
                    self.send(format!("{}", err))
                } else {
                    self.send(buf)
                }
            },
            Err(ref err) if err.kind() == ErrorKind::NotFound => self.end(Status::NotFound),
            Err(ref err) => {
                self.status(Status::InternalServerError).content_type("text/plain");
                self.send(format!("{}", err))
            }
        }
    }

    /// Writes the body of this response using the given source function.
    pub fn stream<F, R>(&mut self, source: F) -> Result<()> where F: FnOnce(&mut Write) -> Result<R> {
        //let mut streaming = try!(self.inner.start());
        //try!(source(&mut streaming));
        //streaming.end()
        Ok(())
    }

    /// Sets a cookie with the given name and value.
    /// If set, the set_options function will be called to update the cookie's options.
    pub fn cookie<F>(&mut self, name: &str, value: &str, set_options: Option<F>) where F: Fn(&mut Cookie) {
        let mut cookie = Cookie::new(name.to_owned(), value.to_owned());
        set_options.map(|f| f(&mut cookie));

        if self.resp().has_header::<SetCookie>() {
            self.resp().push_cookie(cookie)
        } else {
            self.resp().header(SetCookie(vec![cookie]))
        }
    }
}
<commit_msg>simplified Response::cookie method<commit_after>use hyper::header::{CookiePair as Cookie, ContentLength, ContentType, Header, Location, SetCookie};
use hyper::status::StatusCode as Status;

use hyper::{Control, Headers, Next};

use hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value};

use handlebars::Handlebars;
use serde::ser::Serialize as ToJson;

pub use serde_json::value as value;

use std::fmt::Debug;
use std::borrow::Cow;
use std::io::{ErrorKind, Read, Result, Write};
use std::fs::{File, read_dir};
use std::path::Path;

use std::cell::RefCell;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};

use buffer::Buffer;

#[derive(Debug)]
pub struct Resp {
    status: RefCell<Status>,
    headers: RefCell<Headers>,
    body: RefCell<Buffer>,

    notify: AtomicBool,
    ctrl: Control
}

// no worries, the resp is always modified by only one thread at a time
unsafe impl Sync for Resp {}

impl Resp {
    pub fn new(ctrl: Control) -> Resp {
        Resp {
            status: RefCell::new(Status::Ok),
            headers: RefCell::new(Headers::default()),
            body: RefCell::new(Buffer::new()),

            notify: AtomicBool::new(false),
            ctrl: ctrl
        }
    }

    fn status(&self, status: Status) {
        *self.status.borrow_mut() = status;
    }

    fn has_header<H: Header>(&self) -> bool {
        self.headers.borrow().has::<H>()
    }

    fn header<H: Header>(&self, header: H) {
        self.headers.borrow_mut().set(header);
    }

    fn header_raw<K: Into<Cow<'static, str>> + Debug>(&self, name: K, value: Vec<Vec<u8>>) {
        self.headers.borrow_mut().set_raw(name, value);
    }

    fn push_cookie(&self, cookie: Cookie) {
        self.headers.borrow_mut().get_mut::<SetCookie>().unwrap().push(cookie)
    }

    fn len(&self) -> usize {
        self.body.borrow().len()
    }

    fn append<D: AsRef<[u8]>>(&self, content: D) {
        self.body.borrow_mut().append(content.as_ref());
    }

    fn send<D: Into<Vec<u8>>>(&self, content: D) {
        self.body.borrow_mut().send(content);
    }

    pub fn deconstruct(self) -> (Status, Headers, Buffer) {
        (self.status.into_inner(),
        self.headers.into_inner(),
        self.body.into_inner())
    }

    fn done(&self) {
        if self.notify.load(Ordering::Acquire) {
            self.ctrl.ready(Next::write()).unwrap();
        }
    }
}

pub fn set_notify(resp: &Option<Arc<Resp>>) {
    if let Some(ref arc) = *resp {
        arc.notify.store(true, Ordering::Release);
    }
}

/// This represents the response that will be sent back to the application.
///
/// Includes a status code (default 200 OK), headers, and a body.
/// The response can be updated and sent back immediately in a synchronous way,
/// or deferred pending some computation (asynchronous mode).
///
/// The response is sent when it is dropped.
pub struct Response {
    resp: Option<Arc<Resp>>
}

impl Drop for Response {
    fn drop(&mut self) {
        // this is to make sure that we remove this Response's strong reference to Resp
        // *before* we notify the handler, so the call to Arc::get_mut succeeds
        let resp = self.resp.as_ref().unwrap().as_ref() as *const Resp;

        // drop Arc
        {
            self.resp.take().unwrap();
        }

        // no worries: Resp is not dropped when the Arc is dropped,
        // because the handler outlives us, therefore the pointer is always valid here.
        unsafe {
            (*resp).done();
        }
    }
}

fn register_partials(handlebars: &mut Handlebars) -> Result<()> {
    for it in try!(read_dir("views/partials")) {
        let entry = try!(it);
        let path = entry.path();
        if path.extension().is_some() && path.extension().unwrap() == "hbs" {
            let name = path.file_stem().unwrap().to_str().unwrap();
            handlebars.register_template_file(name, path.as_path()).unwrap();
        }
    }
    Ok(())
}

pub fn new(resp: &Option<Arc<Resp>>) -> Response {
    Response {
        resp: Some(resp.as_ref().unwrap().clone())
    }
}

impl Response {

    fn resp(&self) -> &Resp {
        &self.resp.as_ref().unwrap()
    }

    /// Sets the status code of this response.
    pub fn status(&mut self, status: Status) -> &mut Self {
        self.resp().status(status);
        self
    }

    /// Sets the Content-Type header.
    pub fn content_type<S: Into<Vec<u8>>>(&mut self, mime: S) -> &mut Self {
        self.header_raw("Content-Type", mime)
    }

    /// Sets the Content-Length header.
    pub fn len(&mut self, len: u64) -> &mut Self {
        self.header(ContentLength(len))
    }

    /// Sets the Location header.
    pub fn location<S: Into<String>>(&mut self, url: S) -> &mut Self {
        self.header(Location(url.into()))
    }

    /// Redirects to the given URL with the given status, or 302 Found if none is given.
    pub fn redirect(mut self, url: &str, status: Option<Status>) {
        self.location(url);
        self.end(status.unwrap_or(Status::Found))
    }

    /// Sets the given header.
    pub fn header<H: Header>(&mut self, header: H) -> &mut Self {
        self.resp().header(header);
        self
    }

    /// Sets the given header with raw strings.
    pub fn header_raw<K: Into<Cow<'static, str>> + Debug, V: Into<Vec<u8>>>(&mut self, name: K, value: V) -> &mut Self {
        self.resp().header_raw(name, vec![value.into()]);
        self
    }

    /// Ends this response with the given status and an empty body
    pub fn end(mut self, status: Status) {
        self.status(status);
        self.len(0);
    }

    /// Renders the template at the given path using the given data.
    pub fn render<P: AsRef<Path>, T: ToJson>(self, path: P, data: T) {
        let mut handlebars = Handlebars::new();
        let path = path.as_ref();
        let name = path.file_stem().unwrap().to_str().unwrap();

        handlebars.register_template_file(name, path).unwrap();
        register_partials(&mut handlebars).unwrap();
        let result = handlebars.render(name, &data);
        self.send(result.unwrap())
    }

    /// Sends the given content and ends this response.
    /// Status defaults to 200 Ok, headers must have been set before this method is called.
    pub fn send<D: Into<Vec<u8>>>(mut self, content: D) {
        self.resp().send(content);
        let length = self.resp().len();
        self.len(length as u64);
    }

    /// Appends the given content to this response's body.
    /// Will change to support asynchronous use case.
    pub fn append<D: AsRef<[u8]>>(&mut self, content: D) {
        self.resp().append(content);
        let length = self.resp().len() as u64;
        self.len(length);
    }

    /// Sends the given file, setting the Content-Type based on the file's extension.
    /// Known extensions are htm, html, jpg, jpeg, png, js, css.
    /// If the file does not exist, this method sends a 404 Not Found response.
    pub fn send_file<P: AsRef<Path>>(mut self, path: P) {
        if !self.resp().has_header::<ContentType>() {
            let extension = path.as_ref().extension();
            if let Some(ext) = extension {
                let content_type = match ext.to_string_lossy().as_ref() {
                    "htm" | "html" => Some(ContentType::html()),
                    "jpg" | "jpeg" => Some(ContentType::jpeg()),
                    "png" => Some(ContentType::png()),
                    "js" => Some(ContentType(Mime(TopLevel::Text, SubLevel::Javascript, vec![(Attr::Charset, Value::Utf8)]))),
                    "css" => Some(ContentType(Mime(TopLevel::Text, SubLevel::Css, vec![(Attr::Charset, Value::Utf8)]))),
                    _ => None
                };

                if let Some(content_type) = content_type {
                    self.resp().header(content_type);
                }
            }
        }

        // read the whole file at once and send it
        // probably not the best idea for big files, we should use stream instead in that case
        match File::open(path) {
            Ok(mut file) => {
                let mut buf = Vec::with_capacity(file.metadata().ok().map_or(1024, |meta| meta.len() as usize));
                if let Err(err) = file.read_to_end(&mut buf) {
                    self.status(Status::InternalServerError).content_type("text/plain");
                    self.send(format!("{}", err))
                } else {
                    self.send(buf)
                }
            },
            Err(ref err) if err.kind() == ErrorKind::NotFound => self.end(Status::NotFound),
            Err(ref err) => {
                self.status(Status::InternalServerError).content_type("text/plain");
                self.send(format!("{}", err))
            }
        }
    }

    /*
    /// Writes the body of this response using the given source function.
    pub fn stream<F, R>(&mut self, source: F) -> Result<()> where F: FnOnce(&mut Write) -> Result<R> {
        //let mut streaming = try!(self.inner.start());
        //try!(source(&mut streaming));
        //streaming.end()
        Ok(())
    }
    */

    /// Sets the given cookie.
    pub fn cookie(&mut self, cookie: Cookie) {
        if self.resp().has_header::<SetCookie>() {
            self.resp().push_cookie(cookie)
        } else {
            self.resp().header(SetCookie(vec![cookie]))
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The standard RNG

use crate::{RngCore, CryptoRng, Error, SeedableRng};

#[cfg(all(any(test, feature = "std"), target_os = "emscripten"))]
pub(crate) use rand_hc::Hc128Core as Core;
#[cfg(all(any(test, feature = "std"), not(target_os = "emscripten")))]
pub(crate) use rand_chacha::ChaCha20Core as Core;

#[cfg(target_os = "emscripten")] use rand_hc::Hc128Rng as Rng;
#[cfg(not(target_os = "emscripten"))] use rand_chacha::ChaCha20Rng as Rng;

/// The standard RNG. The PRNG algorithm in `StdRng` is chosen to be efficient
/// on the current platform, to be statistically strong and unpredictable
/// (meaning a cryptographically secure PRNG).
///
/// The current algorithm used is the ChaCha block cipher with either 20 or 12
/// rounds (see the `stdrng_*` feature flags, documented in the README).
/// This may change as new evidence of cipher security and performance
/// becomes available.
///
/// The algorithm is deterministic but should not be considered reproducible
/// due to dependence on configuration and possible replacement in future
/// library versions. For a secure reproducible generator, we recommend use of
/// the [rand_chacha] crate directly.
///
/// [rand_chacha]: https://crates.io/crates/rand_chacha
#[derive(Clone, Debug)]
pub struct StdRng(Rng);

impl RngCore for StdRng {
    #[inline(always)]
    fn next_u32(&mut self) -> u32 {
        self.0.next_u32()
    }

    #[inline(always)]
    fn next_u64(&mut self) -> u64 {
        self.0.next_u64()
    }

    #[inline(always)]
    fn fill_bytes(&mut self, dest: &mut [u8]) {
        self.0.fill_bytes(dest);
    }

    #[inline(always)]
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
        self.0.try_fill_bytes(dest)
    }
}

impl SeedableRng for StdRng {
    type Seed = <Rng as SeedableRng>::Seed;

    #[inline(always)]
    fn from_seed(seed: Self::Seed) -> Self {
        StdRng(Rng::from_seed(seed))
    }

    #[inline(always)]
    fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> {
        Rng::from_rng(rng).map(StdRng)
    }
}

impl CryptoRng for StdRng {}

#[cfg(test)]
mod test {
    use crate::{RngCore, SeedableRng};
    use crate::rngs::StdRng;

    #[test]
    fn test_stdrng_construction() {
        // Test value-stability of StdRng. This is expected to break any time
        // the algorithm is changed.
        let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
                    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];

        #[cfg(any(feature="stdrng_strong", not(feature="stdrng_fast")))]
        let target = [3950704604716924505, 5573172343717151650];
        #[cfg(all(not(feature="stdrng_strong"), feature="stdrng_fast"))]
        let target = [10719222850664546238, 14064965282130556830];

        let mut rng0 = StdRng::from_seed(seed);
        let x0 = rng0.next_u64();

        let mut rng1 = StdRng::from_rng(rng0).unwrap();
        let x1 = rng1.next_u64();

        assert_eq!([x0, x1], target);
    }
}
<commit_msg>doc: fix #902 (mention of non-existent configuration for StdRng)<commit_after>// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The standard RNG

use crate::{RngCore, CryptoRng, Error, SeedableRng};

#[cfg(all(any(test, feature = "std"), target_os = "emscripten"))]
pub(crate) use rand_hc::Hc128Core as Core;
#[cfg(all(any(test, feature = "std"), not(target_os = "emscripten")))]
pub(crate) use rand_chacha::ChaCha20Core as Core;

#[cfg(target_os = "emscripten")] use rand_hc::Hc128Rng as Rng;
#[cfg(not(target_os = "emscripten"))] use rand_chacha::ChaCha20Rng as Rng;

/// The standard RNG. The PRNG algorithm in `StdRng` is chosen to be efficient
/// on the current platform, to be statistically strong and unpredictable
/// (meaning a cryptographically secure PRNG).
///
/// The current algorithm used is the ChaCha block cipher with 20 rounds.
/// This may change as new evidence of cipher security and performance
/// becomes available.
///
/// The algorithm is deterministic but should not be considered reproducible
/// due to dependence on configuration and possible replacement in future
/// library versions. For a secure reproducible generator, we recommend use of
/// the [rand_chacha] crate directly.
///
/// [rand_chacha]: https://crates.io/crates/rand_chacha
#[derive(Clone, Debug)]
pub struct StdRng(Rng);

impl RngCore for StdRng {
    #[inline(always)]
    fn next_u32(&mut self) -> u32 {
        self.0.next_u32()
    }

    #[inline(always)]
    fn next_u64(&mut self) -> u64 {
        self.0.next_u64()
    }

    #[inline(always)]
    fn fill_bytes(&mut self, dest: &mut [u8]) {
        self.0.fill_bytes(dest);
    }

    #[inline(always)]
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
        self.0.try_fill_bytes(dest)
    }
}

impl SeedableRng for StdRng {
    type Seed = <Rng as SeedableRng>::Seed;

    #[inline(always)]
    fn from_seed(seed: Self::Seed) -> Self {
        StdRng(Rng::from_seed(seed))
    }

    #[inline(always)]
    fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> {
        Rng::from_rng(rng).map(StdRng)
    }
}

impl CryptoRng for StdRng {}

#[cfg(test)]
mod test {
    use crate::{RngCore, SeedableRng};
    use crate::rngs::StdRng;

    #[test]
    fn test_stdrng_construction() {
        // Test value-stability of StdRng. This is expected to break any time
        // the algorithm is changed.
        let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
                    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];

        #[cfg(any(feature="stdrng_strong", not(feature="stdrng_fast")))]
        let target = [3950704604716924505, 5573172343717151650];
        #[cfg(all(not(feature="stdrng_strong"), feature="stdrng_fast"))]
        let target = [10719222850664546238, 14064965282130556830];

        let mut rng0 = StdRng::from_seed(seed);
        let x0 = rng0.next_u64();

        let mut rng1 = StdRng::from_rng(rng0).unwrap();
        let x1 = rng1.next_u64();

        assert_eq!([x0, x1], target);
    }
}
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/*!
# Rust-PortAudio

__Portaudio__ bindings for Rust

PortAudio provides a uniform application programming interface (API) across all
supported platforms.  You can think of the PortAudio library as a wrapper that
converts calls to the PortAudio API into calls to platform-specific native audio
APIs. Operating systems often offer more than one native audio API and some APIs
(such as JACK) may be available on multiple target operating systems.
PortAudio supports all the major native audio APIs on each supported platform.

# Installation

You must install on your computer the Portaudio libraries who is used for
the binding.

Portaudio is available with package management tools on Linux, or brew on Mac OS.

You can download it directly from the website :
[portaudio](http://www.portaudio.com/download.html)

Then clone the repo and build the library with the following command at the root
of the __rust-portaudio__ repository.

__rust-portaudio__ is build with the rustpkg tool :

```Shell
> rustpkg build portaudio
```

*/

#![crate_id = "portaudio#0.1"]

#![comment = "Portaudio binding for Rust"]
#![license = "MIT"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![feature(globs)]
#![warn(missing_doc)]
#![allow(dead_code)]
#![allow(visible_private_types)]

extern crate libc;

#[cfg(target_os="macos")]
#[cfg(target_os="linux")]
#[cfg(target_os="win32")]
mod c_library {
    #[link(name = "portaudio")]
    extern {}
}

pub mod types;
pub mod pa;

//#[doc(hidden)]
//pub mod user_traits;
//#[doc(hidden)]
//#[cfg(target_os="macos")]
//pub mod mac_core;
//pub mod asio;
#[doc(hidden)]
mod ffi;
<commit_msg>update to last Rust - crate_id -> crate_name<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/*!
# Rust-PortAudio

__Portaudio__ bindings for Rust

PortAudio provides a uniform application programming interface (API) across all
supported platforms.  You can think of the PortAudio library as a wrapper that
converts calls to the PortAudio API into calls to platform-specific native audio
APIs. Operating systems often offer more than one native audio API and some APIs
(such as JACK) may be available on multiple target operating systems.
PortAudio supports all the major native audio APIs on each supported platform.

# Installation

You must install on your computer the Portaudio libraries who is used for
the binding.

Portaudio is available with package management tools on Linux, or brew on Mac OS.

You can download it directly from the website :
[portaudio](http://www.portaudio.com/download.html)

Then clone the repo and build the library with the following command at the root
of the __rust-portaudio__ repository.

__rust-portaudio__ is build with the rustpkg tool :

```Shell
> rustpkg build portaudio
```

*/

#![crate_name = "portaudio"]

#![comment = "Portaudio binding for Rust"]
#![license = "MIT"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![feature(globs)]
#![warn(missing_doc)]
#![allow(dead_code)]
#![allow(visible_private_types)]

extern crate libc;

#[cfg(target_os="macos")]
#[cfg(target_os="linux")]
#[cfg(target_os="win32")]
mod c_library {
    #[link(name = "portaudio")]
    extern {}
}

pub mod types;
pub mod pa;

//#[doc(hidden)]
//pub mod user_traits;
//#[doc(hidden)]
//#[cfg(target_os="macos")]
//pub mod mac_core;
//pub mod asio;
#[doc(hidden)]
mod ffi;
<|endoftext|>


<commit_before>//! Composition tools

use rotor::mio::EventSet;
use rotor::void::{Void, unreachable};
use rotor::{Machine, Scope, Response};

/// Composes two state machines where of the state machines spawns
/// multiple instances of another one
pub enum Spawn<S: Spawner> {
    Spawner(S),
    Child(S::Child),
}

pub trait Spawner: Machine<Seed=Void> {
    type Child: Machine<Context=Self::Context, Seed=Void>;
    type Seed;

    fn spawn(seed: <Self as Spawner>::Seed,
        scope: &mut Scope<<<Self as Spawner>::Child as Machine>::Context>)
        -> Response<Self::Child, Void>;
}

impl<S> Machine for Spawn<S>
    where S: Spawner,
{
    type Context = <S::Child as Machine>::Context;
    type Seed = <S as Spawner>::Seed;

    fn create(seed: <S as Spawner>::Seed, scope: &mut Scope<Self::Context>)
        -> Response<Self, Void>
    {
        S::spawn(seed, scope).wrap(Spawn::Child)
    }
    fn ready(self, events: EventSet, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.ready(events, scope)
                             .map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.ready(events, scope)
                           .map(Child, |x| unreachable(x)) }
        }
    }
    fn spawned(self, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.spawned(scope).map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.spawned(scope).map(Child, |x| unreachable(x)) }
        }
    }
    fn timeout(self, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.timeout(scope).map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.timeout(scope).map(Child, |x| unreachable(x)) }
        }
    }
    fn wakeup(self, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.wakeup(scope).map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.wakeup(scope).map(Child, |x| unreachable(x)) }
        }
    }
}
<commit_msg>Implement Spawner for Uniform<commit_after>//! Composition tools

use rotor::mio::EventSet;
use rotor::void::{Void, unreachable};
use rotor::{Machine, Scope, Response};

/// Composes two state machines where of the state machines spawns
/// multiple instances of another one
pub enum Spawn<S: Spawner> {
    Spawner(S),
    Child(S::Child),
}

pub trait Spawner: Machine<Seed=Void> {
    type Child: Machine<Context=Self::Context, Seed=Void>;
    type Seed;

    fn spawn(seed: <Self as Spawner>::Seed,
        scope: &mut Scope<<<Self as Spawner>::Child as Machine>::Context>)
        -> Response<Self::Child, Void>;
}

impl<T, C> Spawner for ::uniform::Uniform<T>
    where T: Spawner<Context=C> + ::uniform::Action<Seed=Void, Context=C>
{
    type Child = T::Child;
    type Seed = <T as Spawner>::Seed;

    fn spawn(seed: <Self as Spawner>::Seed,
        scope: &mut Scope<<<Self as Spawner>::Child as Machine>::Context>)
        -> Response<Self::Child, Void>
    {
        T::spawn(seed, scope)
    }
}

impl<S> Machine for Spawn<S>
    where S: Spawner,
{
    type Context = <S::Child as Machine>::Context;
    type Seed = <S as Spawner>::Seed;

    fn create(seed: <S as Spawner>::Seed, scope: &mut Scope<Self::Context>)
        -> Response<Self, Void>
    {
        S::spawn(seed, scope).wrap(Spawn::Child)
    }
    fn ready(self, events: EventSet, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.ready(events, scope)
                             .map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.ready(events, scope)
                           .map(Child, |x| unreachable(x)) }
        }
    }
    fn spawned(self, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.spawned(scope).map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.spawned(scope).map(Child, |x| unreachable(x)) }
        }
    }
    fn timeout(self, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.timeout(scope).map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.timeout(scope).map(Child, |x| unreachable(x)) }
        }
    }
    fn wakeup(self, scope: &mut Scope<Self::Context>)
        -> Response<Self, Self::Seed>
    {
        use self::Spawn::*;
        match self {
            Spawner(m) => { m.wakeup(scope).map(Spawner, |x| unreachable(x)) }
            Child(m) => { m.wakeup(scope).map(Child, |x| unreachable(x)) }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

use std::{marker, rc, sync};

use crate::ffi;
use crate::python::Python;

static START: sync::Once = sync::Once::new();

/// Prepares the use of Python in a free-threaded context.
///
/// If the Python interpreter is not already initialized, this function
/// will initialize it with disabled signal handling
/// (Python will not raise the `KeyboardInterrupt` exception).
/// Python signal handling depends on the notion of a 'main thread', which must be
/// the thread that initializes the Python interpreter.
///
/// If both the Python interpreter and Python threading are already initialized,
/// this function has no effect.
///
/// # Panic
/// If the Python interpreter is initialized but Python threading is not,
/// a panic occurs.
/// It is not possible to safely access the Python runtime unless the main
/// thread (the thread which originally initialized Python) also initializes
/// threading.
///
/// When writing an extension module, the `py_module_initializer!` macro
/// will ensure that Python threading is initialized.
///
pub fn prepare_freethreaded_python() {
    // Protect against race conditions when Python is not yet initialized
    // and multiple threads concurrently call 'prepare_freethreaded_python()'.
    // Note that we do not protect against concurrent initialization of the Python runtime
    // by other users of the Python C API.
    START.call_once(|| unsafe {
        if ffi::Py_IsInitialized() != 0 {
            // If Python is already initialized, we expect Python threading to also be initialized,
            // as we can't make the existing Python main thread acquire the GIL.
            assert!(ffi::PyEval_ThreadsInitialized() != 0);
        } else {
            #[cfg(feature = "python27-sys")]
            {
                // If Python isn't initialized yet, we expect that Python threading isn't initialized either.
                assert!(ffi::PyEval_ThreadsInitialized() == 0);
                // Note: starting with Python 3.2 it's no longer possible to initialize threading
                // without initializing Python; and in Python 3.7 PyEval_ThreadsInitialized() started
                // misbehaving when Python was not initialized yet.
            }
            // Initialize Python.
            // We use Py_InitializeEx() with initsigs=0 to disable Python signal handling.
            // Signal handling depends on the notion of a 'main thread', which doesn't exist in this case.
            // Note that the 'main thread' notion in Python isn't documented properly;
            // and running Python without one is not officially supported.
            ffi::Py_InitializeEx(0);
            ffi::PyEval_InitThreads();
            // PyEval_InitThreads() will acquire the GIL,
            // but we don't want to hold it at this point
            // (it's not acquired in the other code paths)
            // So immediately release the GIL:
            let _thread_state = ffi::PyEval_SaveThread();
            // Note that the PyThreadState returned by PyEval_SaveThread is also held in TLS by the Python runtime,
            // and will be restored by PyGILState_Ensure.
        }
    });
}

/// RAII type that represents the Global Interpreter Lock acquisition.
///
/// # Example
/// ```
/// use cpython::Python;
///
/// {
///     let gil_guard = Python::acquire_gil();
///     let py = gil_guard.python();
/// } // GIL is released when gil_guard is dropped
/// ```
#[must_use]
pub struct GILGuard {
    gstate: ffi::PyGILState_STATE,
    // hack to opt out of Send on stable rust, which doesn't
    // have negative impls
    no_send: marker::PhantomData<rc::Rc<()>>,
}

/// The Drop implementation for GILGuard will release the GIL.
impl Drop for GILGuard {
    fn drop(&mut self) {
        unsafe { ffi::PyGILState_Release(self.gstate) }
    }
}

impl GILGuard {
    /// Acquires the global interpreter lock, which allows access to the Python runtime.
    ///
    /// If the Python runtime is not already initialized, this function will initialize it.
    /// See [prepare_freethreaded_python()](fn.prepare_freethreaded_python.html) for details.
    pub fn acquire() -> GILGuard {
        if !cfg!(feature = "no-auto-initialize") {
            crate::pythonrun::prepare_freethreaded_python();
        }
        let gstate = unsafe { ffi::PyGILState_Ensure() }; // acquire GIL
        GILGuard {
            gstate,
            no_send: marker::PhantomData,
        }
    }

    /// Retrieves the marker type that proves that the GIL was acquired.
    #[inline]
    pub fn python(&self) -> Python<'_> {
        unsafe { Python::assume_gil_acquired() }
    }

    /// Checks if the current thread holds the GIL.
    #[cfg(Py_3_4)]
    pub fn check() -> bool {
        let gstate = unsafe { ffi::PyGILState_Check() };
        gstate == 1
    }
}

/// Mutex-like wrapper object for data that is protected by the Python GIL.
///
/// # Example
/// ```
/// use std::cell::Cell;
/// use cpython::{Python, GILProtected};
///
/// let data = GILProtected::new(Cell::new(0));
///
/// {
///     let gil_guard = Python::acquire_gil();
///     let cell = data.get(gil_guard.python());
///     cell.set(cell.get() + 1);
/// }
/// ```
pub struct GILProtected<T> {
    data: T,
}

unsafe impl<T: Send> Send for GILProtected<T> {}

/// Because `GILProtected` ensures that the contained data
/// is only accessed while the GIL is acquired,
/// it can implement `Sync` even if the contained data
/// does not.
unsafe impl<T: Send> Sync for GILProtected<T> {}

impl<T> GILProtected<T> {
    /// Creates a new instance of `GILProtected`.
    #[inline]
    pub const fn new(data: T) -> GILProtected<T> {
        GILProtected { data }
    }

    /// Returns a shared reference to the data stored in the `GILProtected`.
    ///
    /// Requires a `Python` instance as proof that the GIL is acquired.
    #[inline]
    pub fn get<'a>(&'a self, _py: Python<'a>) -> &'a T {
        &self.data
    }

    /// Consumes the `GILProtected`, returning the wrapped value.
    #[inline]
    pub fn into_inner(self) -> T {
        self.data
    }
}
<commit_msg>Fix GILGuard::check never being compiled<commit_after>// Copyright (c) 2015 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

use std::{marker, rc, sync};

use crate::ffi;
use crate::python::Python;

static START: sync::Once = sync::Once::new();

/// Prepares the use of Python in a free-threaded context.
///
/// If the Python interpreter is not already initialized, this function
/// will initialize it with disabled signal handling
/// (Python will not raise the `KeyboardInterrupt` exception).
/// Python signal handling depends on the notion of a 'main thread', which must be
/// the thread that initializes the Python interpreter.
///
/// If both the Python interpreter and Python threading are already initialized,
/// this function has no effect.
///
/// # Panic
/// If the Python interpreter is initialized but Python threading is not,
/// a panic occurs.
/// It is not possible to safely access the Python runtime unless the main
/// thread (the thread which originally initialized Python) also initializes
/// threading.
///
/// When writing an extension module, the `py_module_initializer!` macro
/// will ensure that Python threading is initialized.
///
pub fn prepare_freethreaded_python() {
    // Protect against race conditions when Python is not yet initialized
    // and multiple threads concurrently call 'prepare_freethreaded_python()'.
    // Note that we do not protect against concurrent initialization of the Python runtime
    // by other users of the Python C API.
    START.call_once(|| unsafe {
        if ffi::Py_IsInitialized() != 0 {
            // If Python is already initialized, we expect Python threading to also be initialized,
            // as we can't make the existing Python main thread acquire the GIL.
            assert!(ffi::PyEval_ThreadsInitialized() != 0);
        } else {
            #[cfg(feature = "python27-sys")]
            {
                // If Python isn't initialized yet, we expect that Python threading isn't initialized either.
                assert!(ffi::PyEval_ThreadsInitialized() == 0);
                // Note: starting with Python 3.2 it's no longer possible to initialize threading
                // without initializing Python; and in Python 3.7 PyEval_ThreadsInitialized() started
                // misbehaving when Python was not initialized yet.
            }
            // Initialize Python.
            // We use Py_InitializeEx() with initsigs=0 to disable Python signal handling.
            // Signal handling depends on the notion of a 'main thread', which doesn't exist in this case.
            // Note that the 'main thread' notion in Python isn't documented properly;
            // and running Python without one is not officially supported.
            ffi::Py_InitializeEx(0);
            ffi::PyEval_InitThreads();
            // PyEval_InitThreads() will acquire the GIL,
            // but we don't want to hold it at this point
            // (it's not acquired in the other code paths)
            // So immediately release the GIL:
            let _thread_state = ffi::PyEval_SaveThread();
            // Note that the PyThreadState returned by PyEval_SaveThread is also held in TLS by the Python runtime,
            // and will be restored by PyGILState_Ensure.
        }
    });
}

/// RAII type that represents the Global Interpreter Lock acquisition.
///
/// # Example
/// ```
/// use cpython::Python;
///
/// {
///     let gil_guard = Python::acquire_gil();
///     let py = gil_guard.python();
/// } // GIL is released when gil_guard is dropped
/// ```
#[must_use]
pub struct GILGuard {
    gstate: ffi::PyGILState_STATE,
    // hack to opt out of Send on stable rust, which doesn't
    // have negative impls
    no_send: marker::PhantomData<rc::Rc<()>>,
}

/// The Drop implementation for GILGuard will release the GIL.
impl Drop for GILGuard {
    fn drop(&mut self) {
        unsafe { ffi::PyGILState_Release(self.gstate) }
    }
}

impl GILGuard {
    /// Acquires the global interpreter lock, which allows access to the Python runtime.
    ///
    /// If the Python runtime is not already initialized, this function will initialize it.
    /// See [prepare_freethreaded_python()](fn.prepare_freethreaded_python.html) for details.
    pub fn acquire() -> GILGuard {
        if !cfg!(feature = "no-auto-initialize") {
            crate::pythonrun::prepare_freethreaded_python();
        }
        let gstate = unsafe { ffi::PyGILState_Ensure() }; // acquire GIL
        GILGuard {
            gstate,
            no_send: marker::PhantomData,
        }
    }

    /// Retrieves the marker type that proves that the GIL was acquired.
    #[inline]
    pub fn python(&self) -> Python<'_> {
        unsafe { Python::assume_gil_acquired() }
    }

    /// Checks if the current thread holds the GIL.
    ///
    /// This method is only available with Python 3.
    #[cfg(feature = "python3-sys")]
    pub fn check() -> bool {
        let gstate = unsafe { ffi::PyGILState_Check() };
        gstate == 1
    }
}

/// Mutex-like wrapper object for data that is protected by the Python GIL.
///
/// # Example
/// ```
/// use std::cell::Cell;
/// use cpython::{Python, GILProtected};
///
/// let data = GILProtected::new(Cell::new(0));
///
/// {
///     let gil_guard = Python::acquire_gil();
///     let cell = data.get(gil_guard.python());
///     cell.set(cell.get() + 1);
/// }
/// ```
pub struct GILProtected<T> {
    data: T,
}

unsafe impl<T: Send> Send for GILProtected<T> {}

/// Because `GILProtected` ensures that the contained data
/// is only accessed while the GIL is acquired,
/// it can implement `Sync` even if the contained data
/// does not.
unsafe impl<T: Send> Sync for GILProtected<T> {}

impl<T> GILProtected<T> {
    /// Creates a new instance of `GILProtected`.
    #[inline]
    pub const fn new(data: T) -> GILProtected<T> {
        GILProtected { data }
    }

    /// Returns a shared reference to the data stored in the `GILProtected`.
    ///
    /// Requires a `Python` instance as proof that the GIL is acquired.
    #[inline]
    pub fn get<'a>(&'a self, _py: Python<'a>) -> &'a T {
        &self.data
    }

    /// Consumes the `GILProtected`, returning the wrapped value.
    #[inline]
    pub fn into_inner(self) -> T {
        self.data
    }
}
<|endoftext|>


<commit_before>extern crate semver;

use std::collections::HashMap;
use std::io::net::ip::IpAddr;
use std::any::Any;

#[deriving(PartialEq, Show, Clone)]
pub enum Scheme {
    Http,
    Https
}

#[deriving(PartialEq, Show, Clone)]
pub enum Host<'a> {
    HostName(&'a str),
    HostIp(IpAddr)
}

#[deriving(PartialEq, Show, Clone)]
pub enum Method<'a> {
    Get,
    Post,
    Put,
    Delete,
    Head,
    Connect,
    Options,
    Trace,

    // RFC-5789
    Patch,
    Purge,

    // WebDAV, Subversion, UPNP
    Other(&'a str)
}

/// A Dictionary for extensions provided by the server or middleware
pub type Extensions = HashMap<&'static str, Box<Any>>;

pub trait Request {
    /// The version of HTTP being used
    fn http_version(&self) -> semver::Version;

    /// The version of the conduit spec being used
    fn conduit_version(&self) -> semver::Version;

    /// The request method, such as GET, POST, PUT, DELETE or PATCH
    fn method<'a>(&'a self) -> Method<'a>;

    /// The scheme part of the request URL
    fn scheme(&self) -> Scheme;

    /// The host part of the requested URL
    fn host<'a>(&'a self) -> Host<'a>;

    /// The initial part of the request URL's path that corresponds
    /// to a virtual root. This allows an application to have a
    /// virtual location that consumes part of the path.
    fn virtual_root<'a>(&'a self) -> Option<&'a str>;

    /// The remainder of the path.
    fn path<'a>(&'a self) -> &'a str;

    /// The portion of the request URL that follows the "?"
    fn query_string<'a>(&'a self) -> Option<&'a str>;

    /// The remote IP address of the client or the last proxy that
    /// sent the request.
    fn remote_ip(&self) -> IpAddr;

    /// The byte-size of the body, if any
    fn content_length(&self) -> Option<uint>;

    /// The request's headers, as conduit::Headers.
    fn headers<'a>(&'a self) -> &'a Headers;

    /// A Reader for the body of the request
    fn body<'a>(&'a mut self) -> &'a mut Reader;

    /// A readable map of extensions
    fn extensions<'a>(&'a self) -> &'a Extensions;

    /// A mutable map of extensions
    fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions;
}

pub type HeaderEntries<'a> = Box<Iterator<(&'a str, Vec<&'a str>)>>;

pub trait Headers {
    /// Find the value of a given header. Multi-line headers are represented
    /// as an array.
    fn find<'a>(&'a self, key: &str) -> Option<Vec<&'a str>>;

    /// Returns true if a particular header exists
    fn has(&self, key: &str) -> bool;

    /// Iterate over all of the available headers.
    fn iter<'a>(&'a self) -> HeaderEntries<'a>;
}

pub struct Response {
    /// The status code as a tuple of the return code and status string
    pub status: (uint, &'static str),

    /// A Map of the headers
    pub headers: HashMap<String, Vec<String>>,

    /// A Writer for body of the response
    pub body: Box<Reader + Send>
}

/// A Handler takes a request and returns a response or an error.
/// By default, a bare function implements `Handler`.
pub trait Handler<E> {
    fn call(&self, request: &mut Request) -> Result<Response, E>;
}

impl<E> Handler<E> for fn(&mut Request) -> Result<Response, E> {
    fn call(&self, request: &mut Request) -> Result<Response, E> {
        (*self)(request)
    }
}
<commit_msg>Make Method a valid hash key<commit_after>extern crate semver;

use std::collections::HashMap;
use std::io::net::ip::IpAddr;
use std::hash::Hash;
use std::any::Any;

#[deriving(PartialEq, Show, Clone)]
pub enum Scheme {
    Http,
    Https
}

#[deriving(PartialEq, Show, Clone)]
pub enum Host<'a> {
    HostName(&'a str),
    HostIp(IpAddr)
}

#[deriving(PartialEq, Hash, Show, Clone)]
pub enum Method<'a> {
    Get,
    Post,
    Put,
    Delete,
    Head,
    Connect,
    Options,
    Trace,

    // RFC-5789
    Patch,
    Purge,

    // WebDAV, Subversion, UPNP
    Other(&'a str)
}

/// A Dictionary for extensions provided by the server or middleware
pub type Extensions = HashMap<&'static str, Box<Any>>;

pub trait Request {
    /// The version of HTTP being used
    fn http_version(&self) -> semver::Version;

    /// The version of the conduit spec being used
    fn conduit_version(&self) -> semver::Version;

    /// The request method, such as GET, POST, PUT, DELETE or PATCH
    fn method<'a>(&'a self) -> Method<'a>;

    /// The scheme part of the request URL
    fn scheme(&self) -> Scheme;

    /// The host part of the requested URL
    fn host<'a>(&'a self) -> Host<'a>;

    /// The initial part of the request URL's path that corresponds
    /// to a virtual root. This allows an application to have a
    /// virtual location that consumes part of the path.
    fn virtual_root<'a>(&'a self) -> Option<&'a str>;

    /// The remainder of the path.
    fn path<'a>(&'a self) -> &'a str;

    /// The portion of the request URL that follows the "?"
    fn query_string<'a>(&'a self) -> Option<&'a str>;

    /// The remote IP address of the client or the last proxy that
    /// sent the request.
    fn remote_ip(&self) -> IpAddr;

    /// The byte-size of the body, if any
    fn content_length(&self) -> Option<uint>;

    /// The request's headers, as conduit::Headers.
    fn headers<'a>(&'a self) -> &'a Headers;

    /// A Reader for the body of the request
    fn body<'a>(&'a mut self) -> &'a mut Reader;

    /// A readable map of extensions
    fn extensions<'a>(&'a self) -> &'a Extensions;

    /// A mutable map of extensions
    fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions;
}

pub type HeaderEntries<'a> = Box<Iterator<(&'a str, Vec<&'a str>)>>;

pub trait Headers {
    /// Find the value of a given header. Multi-line headers are represented
    /// as an array.
    fn find<'a>(&'a self, key: &str) -> Option<Vec<&'a str>>;

    /// Returns true if a particular header exists
    fn has(&self, key: &str) -> bool;

    /// Iterate over all of the available headers.
    fn iter<'a>(&'a self) -> HeaderEntries<'a>;
}

pub struct Response {
    /// The status code as a tuple of the return code and status string
    pub status: (uint, &'static str),

    /// A Map of the headers
    pub headers: HashMap<String, Vec<String>>,

    /// A Writer for body of the response
    pub body: Box<Reader + Send>
}

/// A Handler takes a request and returns a response or an error.
/// By default, a bare function implements `Handler`.
pub trait Handler<E> {
    fn call(&self, request: &mut Request) -> Result<Response, E>;
}

impl<E> Handler<E> for fn(&mut Request) -> Result<Response, E> {
    fn call(&self, request: &mut Request) -> Result<Response, E> {
        (*self)(request)
    }
}
<|endoftext|>


<commit_before>extern crate rusttype;

use display::*;
use shared::*;

/// A virtual scrollable buffer with a scoll offset defining a visible window on the buffer itself.
/// It is composed by a horizontally growable virtual buffer, and an offset that defines what
/// portion of the buffer is actually visible.
///
/// ```text
/// ┌─────────────────────────virtual buffer─────────────────────┐
/// ┌───────────╔═════════════════╗──────────────────────────────┐
/// │▓▓▓▓▓▓▓▓▓▓▓║░░░░░░░░░░░░░░░░░║▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│
/// │▓▓▓▓▓▓▓▓▓▓▓║░░░░░░░░░░░░░░░░░║▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│
/// │▓▓▓▓▓▓▓▓▓▓▓║░░░░░░░░░░░░░░░░░║▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│
/// └───────────╚═════════════════╝──────────────────────────────┘
/// └──offset───┴─visible buffer──┘
/// ```
pub struct Scroller<'a> {
    virtual_buffer: Vec<Column>,
    scroll_offset: usize,
    display: &'a mut Display,
    font: rusttype::Font<'a>,
    font_scale: f32,
}

impl<'a> Scroller<'a> {
    /// Create a new `Scroller` using the provided `Display`.
    pub fn new(display: &'a mut Display) -> Scroller<'a> {
        // Scale values for other fonts found on https://www.dafont.com/:
        // Minecraftia-Regular: 11.0
        // 8-bit pusab: 10.0
        // Pixeled: 14.0
        // Commodore Pixelized v1.2: 10.0
        // 000webfont: ???
        // aerxtabs_memesbruh03: ???
        // slkscr: ???
        // visitor1: ???
        let font_data = include_bytes!("./../fonts/Commodore Pixelized v1.2.ttf");
        let collection = rusttype::FontCollection::from_bytes(font_data as &[u8]);
        let font = collection.into_font().unwrap();
        Scroller {
            virtual_buffer: vec![],
            scroll_offset: 0,
            display: display,
            font: font,
            font_scale: 10.0,
        }
    }

    /// Moves the visible buffer one pixel to the right. When the right side of the visible buffer
    /// reaches the right side of the virtual buffer, it starts again from the beginning.
    pub fn scroll(&mut self) {
        self.scroll_offset += 1;
        if self.scroll_offset >= self.virtual_buffer.len() {
            self.scroll_offset = 0;
        }
    }

    /// Sets the value of an individual pixel in the virtual buffer.
    ///
    /// Coordinates are zero-based, with the origin in the top left corner of the virtual buffer,
    /// and increasing down and to the right.
    ///
    /// If the virtual buffer is not wide enough to contain the pixel, it is automatically extended
    /// up to that size.
    pub fn set_pixel(&mut self, x: usize, y: usize, value: u8) {
        if y >= DISPLAY_HEIGHT {
            return;
        }
        if x >= self.virtual_buffer.len() {
            for _ in self.virtual_buffer.len()..(x + 1) {
                self.virtual_buffer.push(EMPTY_COLUMN);
            }
        }
        self.virtual_buffer[x][y] = value;
    }

    /// Clears the virtual buffer and sets the text to the specified value.
    pub fn set_text(&mut self, text: &str) {
        self.clear();
        let mut start = 0usize;
        for g in self.font.clone().glyphs_for(text.chars()) {
            let scaled_glyph = g.scaled(rusttype::Scale::uniform(self.font_scale));
            let width = scaled_glyph.h_metrics().advance_width as usize;
            let positioned_glyph = scaled_glyph.positioned(rusttype::point(0.0, 0.0));
            positioned_glyph.draw(|x, y, v| {
                let x = x as usize;
                let y = y as usize;
                let v = (v * 255.0) as u8;
                self.set_pixel(start + x, y, v);
            });
            start += width;
        }
    }

    /// Returns the visible buffer taking into account the current scroll offset.
    fn visible_buffer(&self) -> Vec<Column> {
        self.virtual_buffer
            .iter()
            .skip(self.scroll_offset)
            .take(DISPLAY_WIDTH)
            .cloned()
            .collect()
    }

    /// Sends the visible buffer to the output display.
    pub fn show(&mut self) {
        let visible_buffer = self.visible_buffer();
        self.display.show(&visible_buffer).unwrap();
    }

    /// Clears the virtual buffer.
    pub fn clear(&mut self) {
        self.virtual_buffer = vec![];
    }
}
<commit_msg>Call Vec::clear<commit_after>extern crate rusttype;

use display::*;
use shared::*;

/// A virtual scrollable buffer with a scoll offset defining a visible window on the buffer itself.
/// It is composed by a horizontally growable virtual buffer, and an offset that defines what
/// portion of the buffer is actually visible.
///
/// ```text
/// ┌─────────────────────────virtual buffer─────────────────────┐
/// ┌───────────╔═════════════════╗──────────────────────────────┐
/// │▓▓▓▓▓▓▓▓▓▓▓║░░░░░░░░░░░░░░░░░║▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│
/// │▓▓▓▓▓▓▓▓▓▓▓║░░░░░░░░░░░░░░░░░║▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│
/// │▓▓▓▓▓▓▓▓▓▓▓║░░░░░░░░░░░░░░░░░║▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│
/// └───────────╚═════════════════╝──────────────────────────────┘
/// └──offset───┴─visible buffer──┘
/// ```
pub struct Scroller<'a> {
    virtual_buffer: Vec<Column>,
    scroll_offset: usize,
    display: &'a mut Display,
    font: rusttype::Font<'a>,
    font_scale: f32,
}

impl<'a> Scroller<'a> {
    /// Create a new `Scroller` using the provided `Display`.
    pub fn new(display: &'a mut Display) -> Scroller<'a> {
        // Scale values for other fonts found on https://www.dafont.com/:
        // Minecraftia-Regular: 11.0
        // 8-bit pusab: 10.0
        // Pixeled: 14.0
        // Commodore Pixelized v1.2: 10.0
        // 000webfont: ???
        // aerxtabs_memesbruh03: ???
        // slkscr: ???
        // visitor1: ???
        let font_data = include_bytes!("./../fonts/Commodore Pixelized v1.2.ttf");
        let collection = rusttype::FontCollection::from_bytes(font_data as &[u8]);
        let font = collection.into_font().unwrap();
        Scroller {
            virtual_buffer: vec![],
            scroll_offset: 0,
            display: display,
            font: font,
            font_scale: 10.0,
        }
    }

    /// Moves the visible buffer one pixel to the right. When the right side of the visible buffer
    /// reaches the right side of the virtual buffer, it starts again from the beginning.
    pub fn scroll(&mut self) {
        self.scroll_offset += 1;
        if self.scroll_offset >= self.virtual_buffer.len() {
            self.scroll_offset = 0;
        }
    }

    /// Sets the value of an individual pixel in the virtual buffer.
    ///
    /// Coordinates are zero-based, with the origin in the top left corner of the virtual buffer,
    /// and increasing down and to the right.
    ///
    /// If the virtual buffer is not wide enough to contain the pixel, it is automatically extended
    /// up to that size.
    pub fn set_pixel(&mut self, x: usize, y: usize, value: u8) {
        if y >= DISPLAY_HEIGHT {
            return;
        }
        if x >= self.virtual_buffer.len() {
            for _ in self.virtual_buffer.len()..(x + 1) {
                self.virtual_buffer.push(EMPTY_COLUMN);
            }
        }
        self.virtual_buffer[x][y] = value;
    }

    /// Clears the virtual buffer and sets the text to the specified value.
    pub fn set_text(&mut self, text: &str) {
        self.clear();
        let mut start = 0usize;
        for g in self.font.clone().glyphs_for(text.chars()) {
            let scaled_glyph = g.scaled(rusttype::Scale::uniform(self.font_scale));
            let width = scaled_glyph.h_metrics().advance_width as usize;
            let positioned_glyph = scaled_glyph.positioned(rusttype::point(0.0, 0.0));
            positioned_glyph.draw(|x, y, v| {
                let x = x as usize;
                let y = y as usize;
                let v = (v * 255.0) as u8;
                self.set_pixel(start + x, y, v);
            });
            start += width;
        }
    }

    /// Returns the visible buffer taking into account the current scroll offset.
    fn visible_buffer(&self) -> Vec<Column> {
        self.virtual_buffer
            .iter()
            .skip(self.scroll_offset)
            .take(DISPLAY_WIDTH)
            .cloned()
            .collect()
    }

    /// Sends the visible buffer to the output display.
    pub fn show(&mut self) {
        let visible_buffer = self.visible_buffer();
        self.display.show(&visible_buffer).unwrap();
    }

    /// Clears the virtual buffer.
    pub fn clear(&mut self) {
        self.virtual_buffer.clear();
    }
}
<|endoftext|>


<commit_before>use display::*;
use font::*;
use shared::*;

/// A virtual scrollable buffer with a scoll offset defining a visible window on the buffer itself.
pub struct Scroller<'a> {
    scroll: usize,
    buffer: Vec<Column>,
    display: &'a mut Display,
}

impl<'a> Scroller<'a> {
    pub fn new(display: &'a mut Display) -> Scroller {
        Scroller {
            scroll: 0,
            buffer: vec![],
            display: display,
        }
    }

    /// Moves the buffer one pixel to the right.
    pub fn scroll(&mut self) {
        self.scroll += 1;
        if self.scroll >= self.buffer.len() {
            self.scroll = 0;
        }
    }

    /// Sets the value of an individual pixel.
    pub fn set_pixel(&mut self, x: usize, y: usize, value: u8) {
        if y >= DISPLAY_HEIGHT {
            return;
        }
        if x >= self.buffer.len() {
            for _ in self.buffer.len()..(x + 1) {
                self.buffer.push(EMPTY_COLUMN);
            }
        }
        self.buffer[x][y] = value;
    }

    /// Sets the text of the buffer to the specified value.
    pub fn set_text(&mut self, text: &str) {
        self.clear();
        let font = font();
        for c in text.chars() {
            if let Some(glyph) = font.get(&c) {
                for c in glyph {
                    self.buffer.push(*c);
                }
                self.buffer.push(EMPTY_COLUMN);
            }
        }
    }

    /// Sends the buffer to the output display.
    pub fn show(&mut self) {
        let buffer: Vec<Column> =
            self.buffer.iter().skip(self.scroll).take(DISPLAY_WIDTH).cloned().collect();
        self.display.show(&buffer);
    }

    /// Clears the buffer.
    pub fn clear(&mut self) {
        self.buffer = vec![];
    }
}
<commit_msg>Doc diagram.<commit_after>use display::*;
use font::*;
use shared::*;

/// A virtual scrollable buffer with a scoll offset defining a visible window on the buffer itself.
/// It is composed by a horizontally growable virtual buffer, and an offset that defines what
/// portion of the buffer is actually visible.
///
/// ```text
/// ┌─────────────virtual buffer───────────┐
/// ┌───────╔═════════════════╗────────────┐
/// │▓▓▓▓▓▓▓║░░░░░░░░░░░░░░░░░║▓▓▓▓▓▓▓▓▓▓▓▓│
/// │▓▓▓▓▓▓▓║░░░░░░░░░░░░░░░░░║▓▓▓▓▓▓▓▓▓▓▓▓│
/// └───────╚═════════════════╝────────────┘
/// └offset─┴─visible buffer──┘
/// ```
pub struct Scroller<'a> {
    virtual_buffer: Vec<Column>,
    scroll_offset_x: usize,
    display: &'a mut Display,
}

impl<'a> Scroller<'a> {
    pub fn new(display: &'a mut Display) -> Scroller {
        Scroller {
            virtual_buffer: vec![],
            scroll_offset_x: 0,
            display: display,
        }
    }

    /// Moves the buffer one pixel to the right. When the window reaches the end of the virtual
    /// buffer, it starts again from the beginning.
    pub fn scroll(&mut self) {
        self.scroll_offset_x += 1;
        if self.scroll_offset_x >= self.virtual_buffer.len() {
            self.scroll_offset_x = 0;
        }
    }

    /// Sets the value of an individual pixel.
    pub fn set_pixel(&mut self, x: usize, y: usize, value: u8) {
        if y >= DISPLAY_HEIGHT {
            return;
        }
        if x >= self.virtual_buffer.len() {
            for _ in self.virtual_buffer.len()..(x + 1) {
                self.virtual_buffer.push(EMPTY_COLUMN);
            }
        }
        self.virtual_buffer[x][y] = value;
    }

    /// Sets the text of the buffer to the specified value.
    pub fn set_text(&mut self, text: &str) {
        self.clear();
        let font = font();
        for c in text.chars() {
            if let Some(glyph) = font.get(&c) {
                for c in glyph {
                    self.virtual_buffer.push(*c);
                }
                self.virtual_buffer.push(EMPTY_COLUMN);
            }
        }
    }

    fn visible_buffer(&self) -> Vec<Column> {
        self.virtual_buffer
            .iter()
            .skip(self.scroll_offset_x)
            .take(DISPLAY_WIDTH)
            .cloned()
            .collect()
    }

    /// Sends the visible buffer to the output display.
    pub fn show(&mut self) {
        let visible_buffer = self.visible_buffer();
        self.display.show(&visible_buffer);
    }

    /// Clears the buffer.
    pub fn clear(&mut self) {
        self.virtual_buffer = vec![];
    }
}
<|endoftext|>