<commit_before>use std::marker;
use std::io;
use std::sync::Arc;
use std::panic;

use error::ErrorCode;

use solicit::StreamId;
use error::Error;
use solicit::header::*;
use solicit::connection::EndStream;

use bytes::Bytes;

use futures;
use futures::Future;
use futures::stream;
use futures::stream::Stream;

use tokio_io::AsyncRead;
use tokio_io::AsyncWrite;
use tokio_core::net::TcpStream;
use tokio_core::reactor;
use tokio_tls::TlsAcceptorExt;

use futures_misc::*;

use solicit_async::*;
use service::Service;
use stream_part::*;
use common::*;

use server_tls::*;
use server_conf::*;

use misc::any_to_string;

struct ServerStream<F : Service> {
    common: HttpStreamCommon,
    request_handler: Option<futures::sync::mpsc::UnboundedSender<ResultOrEof<HttpStreamPart, Error>>>,
    _marker: marker::PhantomData<F>,
}

impl<F : Service> HttpStream for ServerStream<F> {
    fn first_id() -> StreamId {
        2
    }

    fn common(&self) -> &HttpStreamCommon {
        &self.common
    }

    fn common_mut(&mut self) -> &mut HttpStreamCommon {
        &mut self.common
    }

    fn new_data_chunk(&mut self, data: &[u8], last: bool) {
        if let Some(ref mut sender) = self.request_handler {
            let part = HttpStreamPart {
                content: HttpStreamPartContent::Data(Bytes::from(data)),
                last: last,
            };
            // ignore error
            sender.send(ResultOrEof::Item(part)).ok();
        }
    }

    fn rst(&mut self, error_code: ErrorCode) {
        if let Some(ref mut sender) = self.request_handler {
            // ignore error
            sender.send(ResultOrEof::Error(Error::CodeError(error_code))).ok();
        }
    }

    fn closed_remote(&mut self) {
        if let Some(sender) = self.request_handler.take() {
            // ignore error
            sender.send(ResultOrEof::Eof).ok();
        }
    }
}

impl<F : Service> ServerStream<F> {
    fn set_headers(&mut self, headers: Headers, last: bool) {
        if let Some(ref mut sender) = self.request_handler {
            let part = HttpStreamPart {
                content: HttpStreamPartContent::Headers(headers),
                last: last,
            };
            // ignore error
            sender.send(ResultOrEof::Item(part)).ok();
        }
    }

}

struct ServerInner<F : Service> {
    common: LoopInnerCommon<ServerStream<F>>,
    factory: Arc<F>,
    to_write_tx: futures::sync::mpsc::UnboundedSender<ServerToWriteMessage<F>>,
}

impl<F : Service> ServerInner<F> {
    fn new_request(&mut self, stream_id: StreamId, headers: Headers)
        -> futures::sync::mpsc::UnboundedSender<ResultOrEof<HttpStreamPart, Error>>
    {
        let (req_tx, req_rx) = futures::sync::mpsc::unbounded();

        let req_rx = req_rx.map_err(|()| Error::from(io::Error::new(io::ErrorKind::Other, "req")));
        let req_rx = stream_with_eof_and_error(req_rx, || Error::from(io::Error::new(io::ErrorKind::Other, "unexpected eof")));

        let response = panic::catch_unwind(panic::AssertUnwindSafe(|| {
            self.factory.start_request(headers, HttpPartStream::new(req_rx))
        }));

        let response = response.unwrap_or_else(|e| {
            let e = any_to_string(e);
            warn!("handler panicked: {}", e);

            let headers = Headers::internal_error_500();
            Response::from_stream(stream::iter(vec![
                Ok(HttpStreamPart::intermediate_headers(headers)),
                Ok(HttpStreamPart::last_data(Bytes::from(format!("handler panicked: {}", e)))),
            ]))
        });

        let response = panic::AssertUnwindSafe(response.into_stream_flag()).catch_unwind().then(|r| {
            match r {
                Ok(r) => r,
                Err(e) => {
                    let e = any_to_string(e);
                    // TODO: send plain text error if headers weren't sent yet
                    warn!("handler panicked: {}", e);
                    Err(Error::HandlerPanicked(e))
                },
            }
        });

        {
            let to_write_tx1 = self.to_write_tx.clone();
            let to_write_tx2 = to_write_tx1.clone();

            let process_response = response.for_each(move |part: HttpStreamPart| {
                // drop error if connection is closed
                if let Err(e) = to_write_tx1.send(ServerToWriteMessage::ResponsePart(stream_id, part)) {
                    warn!("failed to write to channel, probably connection is closed: {}", e);
                }
                Ok(())
            }).then(move |r| {
                let error_code =
                    match r {
                        Ok(()) => ErrorCode::NoError,
                        Err(e) => {
                            warn!("handler stream error: {:?}", e);
                            ErrorCode::InternalError
                        }
                    };
                if let Err(e) = to_write_tx2.send(ServerToWriteMessage::ResponseStreamEnd(stream_id, error_code)) {
                    warn!("failed to write to channel, probably connection is closed: {}", e);
                }
                Ok(())
            });

            self.common.loop_handle.spawn(process_response);
        }

        req_tx
    }

    fn new_stream(&mut self, stream_id: StreamId, headers: Headers) -> &mut ServerStream<F> {
        debug!("new stream: {}", stream_id);

        let req_tx = self.new_request(stream_id, headers);

        // New stream initiated by the client
        let stream = ServerStream {
            common: HttpStreamCommon::new(self.common.conn.peer_settings.initial_window_size),
            request_handler: Some(req_tx),
            _marker: marker::PhantomData,
        };
        if let Some(..) = self.common.streams.map.insert(stream_id, stream) {
            panic!("inserted stream that already existed");
        }
        self.common.streams.map.get_mut(&stream_id).unwrap()
    }

    fn get_or_create_stream(&mut self, stream_id: StreamId, headers: Headers, last: bool) -> &mut ServerStream<F> {
        if self.common.streams.get_mut(stream_id).is_some() {
            // https://github.com/rust-lang/rust/issues/36403
            let stream = self.common.streams.get_mut(stream_id).unwrap();
            stream.set_headers(headers, last);
            stream
        } else {
            self.new_stream(stream_id, headers)
        }
    }
}

impl<F : Service> LoopInner for ServerInner<F> {
    type LoopHttpStream = ServerStream<F>;

    fn common(&mut self) -> &mut LoopInnerCommon<ServerStream<F>> {
        &mut self.common
    }

    fn send_common(&mut self, message: CommonToWriteMessage) {
        self.to_write_tx.send(ServerToWriteMessage::Common(message))
            .expect("read to write common");
    }

    fn process_headers(&mut self, stream_id: StreamId, end_stream: EndStream, headers: Headers) {
        let _stream = self.get_or_create_stream(
            stream_id,
            headers,
            end_stream == EndStream::Yes);

        // TODO: drop stream if closed on both ends
    }

}

type ServerReadLoop<F, I> = ReadLoopData<I, ServerInner<F>>;
type ServerWriteLoop<F, I> = WriteLoopData<I, ServerInner<F>>;
type ServerCommandLoop<F> = CommandLoopData<ServerInner<F>>;

enum ServerToWriteMessage<F : Service> {
    _Dummy(F),
    ResponsePart(StreamId, HttpStreamPart),
    // send when user provided handler completed the stream
    ResponseStreamEnd(StreamId, ErrorCode),
    Common(CommonToWriteMessage),
}

enum ServerCommandMessage {
    DumpState(futures::sync::oneshot::Sender<ConnectionStateSnapshot>),
}

impl<F : Service, I : AsyncWrite + Send> ServerWriteLoop<F, I> {
    fn _loop_handle(&self) -> reactor::Handle {
        self.inner.with(move |inner: &mut ServerInner<F>| inner.common.loop_handle.clone())
    }

    fn process_response_part(self, stream_id: StreamId, part: HttpStreamPart) -> HttpFuture<Self> {
        let stream_id = self.inner.with(move |inner: &mut ServerInner<F>| {
            let stream = inner.common.streams.get_mut(stream_id);
            if let Some(stream) = stream {
                if !stream.common.state.is_closed_local() {
                    stream.common.outgoing.push_back(part.content);
                    if part.last {
                        stream.common.outgoing_end = Some(ErrorCode::NoError);
                    }
                    Some(stream_id)
                } else {
                    None
                }
            } else {
                None
            }
        });
        if let Some(stream_id) = stream_id {
            self.send_outg_stream(stream_id)
        } else {
            Box::new(futures::finished(self))
        }
    }

    fn process_response_end(self, stream_id: StreamId, error_code: ErrorCode) -> HttpFuture<Self> {
        let stream_id = self.inner.with(move |inner: &mut ServerInner<F>| {
            let stream = inner.common.streams.get_mut(stream_id);
            if let Some(stream) = stream {
                if stream.common.outgoing_end.is_none() {
                    stream.common.outgoing_end = Some(error_code);
                }
                Some(stream_id)
            } else {
                None
            }
        });
        if let Some(stream_id) = stream_id {
            self.send_outg_stream(stream_id)
        } else {
            Box::new(futures::finished(self))
        }
    }

    fn process_message(self, message: ServerToWriteMessage<F>) -> HttpFuture<Self> {
        match message {
            ServerToWriteMessage::ResponsePart(stream_id, response) => {
                self.process_response_part(stream_id, response)
            },
            ServerToWriteMessage::ResponseStreamEnd(stream_id, error_code) => {
                self.process_response_end(stream_id, error_code)
            },
            ServerToWriteMessage::Common(common) => {
                self.process_common(common)
            },
            ServerToWriteMessage::_Dummy(..) => {
                panic!()
            },
        }
    }

    fn run(self, requests: HttpFutureStream<ServerToWriteMessage<F>>) -> HttpFuture<()> {
        let requests = requests.map_err(Error::from);
        Box::new(requests
            .fold(self, move |wl, message: ServerToWriteMessage<F>| {
                wl.process_message(message)
            })
            .map(|_| ()))
    }
}

impl<F : Service> ServerCommandLoop<F> {
    fn process_dump_state(self, sender: futures::sync::oneshot::Sender<ConnectionStateSnapshot>) -> HttpFuture<Self> {
        // ignore send error, client might be already dead
        drop(sender.send(self.inner.with(|inner| inner.common.dump_state())));
        Box::new(futures::finished(self))
    }

    fn process_message(self, message: ServerCommandMessage) -> HttpFuture<Self> {
        match message {
            ServerCommandMessage::DumpState(sender) => self.process_dump_state(sender),
        }
    }

    fn run(self, requests: HttpFutureStreamSend<ServerCommandMessage>) -> HttpFuture<()> {
        let requests = requests.map_err(Error::from);
        Box::new(requests
            .fold(self, move |l, message: ServerCommandMessage| {
                l.process_message(message)
            })
            .map(|_| ()))
    }}

pub struct ServerConnection {
    command_tx: futures::sync::mpsc::UnboundedSender<ServerCommandMessage>,
}

impl ServerConnection {
    fn connected<F, I>(lh: &reactor::Handle, socket: HttpFutureSend<I>, _conf: ServerConf, service: Arc<F>)
                       -> (ServerConnection, HttpFuture<()>)
        where
            F : Service,
            I : AsyncRead + AsyncWrite + Send + 'static,
    {
        let lh = lh.clone();

        let (to_write_tx, to_write_rx) = futures::sync::mpsc::unbounded::<ServerToWriteMessage<F>>();
        let (command_tx, command_rx) = futures::sync::mpsc::unbounded::<ServerCommandMessage>();

        let to_write_rx = to_write_rx.map_err(|()| Error::IoError(io::Error::new(io::ErrorKind::Other, "to_write")));
        let command_rx = Box::new(command_rx.map_err(|()| Error::IoError(io::Error::new(io::ErrorKind::Other, "command"))));

        let handshake = socket.and_then(server_handshake);

        let run = handshake.and_then(move |socket| {
            let (read, write) = socket.split();

            let inner = TaskRcMut::new(ServerInner {
                common: LoopInnerCommon::new(lh),
                factory: service,
                to_write_tx: to_write_tx.clone(),

            });

            let run_write = ServerWriteLoop { write: write, inner: inner.clone() }.run(Box::new(to_write_rx));
            let run_read = ServerReadLoop { read: read, inner: inner.clone() }.run();
            let run_command = ServerCommandLoop { inner: inner.clone() }.run(command_rx);

            run_write.join(run_read).join(run_command).map(|_| ())
        });

        let future = Box::new(run.then(|x| { info!("connection end: {:?}", x); x }));

        (ServerConnection {
            command_tx: command_tx,
        }, future)
    }

    pub fn new<S>(lh: &reactor::Handle, socket: TcpStream, tls: ServerTlsOption, conf: ServerConf, service: Arc<S>)
                  -> (ServerConnection, HttpFuture<()>)
        where
            S : Service,
    {
        match tls {
            ServerTlsOption::Plain =>
                ServerConnection::connected(
                    lh, Box::new(futures::finished(socket)), conf, service),
            ServerTlsOption::Tls(acceptor) =>
                ServerConnection::connected(
                    lh, Box::new(acceptor.accept_async(socket).map_err(Error::from)), conf, service),
        }
    }

    pub fn new_plain<S>(lh: &reactor::Handle, socket: TcpStream, conf: ServerConf, service: Arc<S>)
                        -> (ServerConnection, HttpFuture<()>)
        where
            S : Service,
    {
        ServerConnection::new(lh, socket, ServerTlsOption::Plain, conf, service)
    }

    pub fn new_plain_fn<F>(lh: &reactor::Handle, socket: TcpStream, conf: ServerConf, f: F)
                           -> (ServerConnection, HttpFuture<()>)
        where
            F : Fn(Headers, HttpPartStream) -> Response + Send + 'static,
    {
        struct HttpServiceFn<F>(F);

        impl<F> Service for HttpServiceFn<F>
            where F : Fn(Headers, HttpPartStream) -> Response + Send + 'static
        {
            fn start_request(&self, headers: Headers, req: HttpPartStream) -> Response {
                (self.0)(headers, req)
            }
        }

        ServerConnection::new_plain(lh, socket, conf, Arc::new(HttpServiceFn(f)))
    }

    /// For tests
    pub fn dump_state(&self) -> HttpFutureSend<ConnectionStateSnapshot> {
        let (tx, rx) = futures::oneshot();

        self.command_tx.clone().send(ServerCommandMessage::DumpState(tx))
            .expect("send request to dump state");

        let rx = rx.map_err(|_| Error::from(io::Error::new(io::ErrorKind::Other, "oneshot canceled")));

        Box::new(rx)
    }

}
<commit_msg>Unnecessary type parameters in server implementation<commit_after>use std::io;
use std::sync::Arc;
use std::panic;

use error::ErrorCode;

use solicit::StreamId;
use error::Error;
use solicit::header::*;
use solicit::connection::EndStream;

use bytes::Bytes;

use futures;
use futures::Future;
use futures::stream;
use futures::stream::Stream;

use tokio_io::AsyncRead;
use tokio_io::AsyncWrite;
use tokio_core::net::TcpStream;
use tokio_core::reactor;
use tokio_tls::TlsAcceptorExt;

use futures_misc::*;

use solicit_async::*;
use service::Service;
use stream_part::*;
use common::*;

use server_tls::*;
use server_conf::*;

use misc::any_to_string;

struct ServerStream {
    common: HttpStreamCommon,
    request_handler: Option<futures::sync::mpsc::UnboundedSender<ResultOrEof<HttpStreamPart, Error>>>,
}

impl HttpStream for ServerStream {
    fn first_id() -> StreamId {
        2
    }

    fn common(&self) -> &HttpStreamCommon {
        &self.common
    }

    fn common_mut(&mut self) -> &mut HttpStreamCommon {
        &mut self.common
    }

    fn new_data_chunk(&mut self, data: &[u8], last: bool) {
        if let Some(ref mut sender) = self.request_handler {
            let part = HttpStreamPart {
                content: HttpStreamPartContent::Data(Bytes::from(data)),
                last: last,
            };
            // ignore error
            sender.send(ResultOrEof::Item(part)).ok();
        }
    }

    fn rst(&mut self, error_code: ErrorCode) {
        if let Some(ref mut sender) = self.request_handler {
            // ignore error
            sender.send(ResultOrEof::Error(Error::CodeError(error_code))).ok();
        }
    }

    fn closed_remote(&mut self) {
        if let Some(sender) = self.request_handler.take() {
            // ignore error
            sender.send(ResultOrEof::Eof).ok();
        }
    }
}

impl ServerStream {
    fn set_headers(&mut self, headers: Headers, last: bool) {
        if let Some(ref mut sender) = self.request_handler {
            let part = HttpStreamPart {
                content: HttpStreamPartContent::Headers(headers),
                last: last,
            };
            // ignore error
            sender.send(ResultOrEof::Item(part)).ok();
        }
    }

}

struct ServerInner {
    common: LoopInnerCommon<ServerStream>,
    factory: Arc<Service>,
    to_write_tx: futures::sync::mpsc::UnboundedSender<ServerToWriteMessage>,
}

impl ServerInner {
    fn new_request(&mut self, stream_id: StreamId, headers: Headers)
        -> futures::sync::mpsc::UnboundedSender<ResultOrEof<HttpStreamPart, Error>>
    {
        let (req_tx, req_rx) = futures::sync::mpsc::unbounded();

        let req_rx = req_rx.map_err(|()| Error::from(io::Error::new(io::ErrorKind::Other, "req")));
        let req_rx = stream_with_eof_and_error(req_rx, || Error::from(io::Error::new(io::ErrorKind::Other, "unexpected eof")));

        let response = panic::catch_unwind(panic::AssertUnwindSafe(|| {
            self.factory.start_request(headers, HttpPartStream::new(req_rx))
        }));

        let response = response.unwrap_or_else(|e| {
            let e = any_to_string(e);
            warn!("handler panicked: {}", e);

            let headers = Headers::internal_error_500();
            Response::from_stream(stream::iter(vec![
                Ok(HttpStreamPart::intermediate_headers(headers)),
                Ok(HttpStreamPart::last_data(Bytes::from(format!("handler panicked: {}", e)))),
            ]))
        });

        let response = panic::AssertUnwindSafe(response.into_stream_flag()).catch_unwind().then(|r| {
            match r {
                Ok(r) => r,
                Err(e) => {
                    let e = any_to_string(e);
                    // TODO: send plain text error if headers weren't sent yet
                    warn!("handler panicked: {}", e);
                    Err(Error::HandlerPanicked(e))
                },
            }
        });

        {
            let to_write_tx1 = self.to_write_tx.clone();
            let to_write_tx2 = to_write_tx1.clone();

            let process_response = response.for_each(move |part: HttpStreamPart| {
                // drop error if connection is closed
                if let Err(e) = to_write_tx1.send(ServerToWriteMessage::ResponsePart(stream_id, part)) {
                    warn!("failed to write to channel, probably connection is closed: {}", e);
                }
                Ok(())
            }).then(move |r| {
                let error_code =
                    match r {
                        Ok(()) => ErrorCode::NoError,
                        Err(e) => {
                            warn!("handler stream error: {:?}", e);
                            ErrorCode::InternalError
                        }
                    };
                if let Err(e) = to_write_tx2.send(ServerToWriteMessage::ResponseStreamEnd(stream_id, error_code)) {
                    warn!("failed to write to channel, probably connection is closed: {}", e);
                }
                Ok(())
            });

            self.common.loop_handle.spawn(process_response);
        }

        req_tx
    }

    fn new_stream(&mut self, stream_id: StreamId, headers: Headers) -> &mut ServerStream {
        debug!("new stream: {}", stream_id);

        let req_tx = self.new_request(stream_id, headers);

        // New stream initiated by the client
        let stream = ServerStream {
            common: HttpStreamCommon::new(self.common.conn.peer_settings.initial_window_size),
            request_handler: Some(req_tx),
        };
        if let Some(..) = self.common.streams.map.insert(stream_id, stream) {
            panic!("inserted stream that already existed");
        }
        self.common.streams.map.get_mut(&stream_id).unwrap()
    }

    fn get_or_create_stream(&mut self, stream_id: StreamId, headers: Headers, last: bool) -> &mut ServerStream {
        if self.common.streams.get_mut(stream_id).is_some() {
            // https://github.com/rust-lang/rust/issues/36403
            let stream = self.common.streams.get_mut(stream_id).unwrap();
            stream.set_headers(headers, last);
            stream
        } else {
            self.new_stream(stream_id, headers)
        }
    }
}

impl LoopInner for ServerInner {
    type LoopHttpStream = ServerStream;

    fn common(&mut self) -> &mut LoopInnerCommon<ServerStream> {
        &mut self.common
    }

    fn send_common(&mut self, message: CommonToWriteMessage) {
        self.to_write_tx.send(ServerToWriteMessage::Common(message))
            .expect("read to write common");
    }

    fn process_headers(&mut self, stream_id: StreamId, end_stream: EndStream, headers: Headers) {
        let _stream = self.get_or_create_stream(
            stream_id,
            headers,
            end_stream == EndStream::Yes);

        // TODO: drop stream if closed on both ends
    }

}

type ServerReadLoop<I> = ReadLoopData<I, ServerInner>;
type ServerWriteLoop<I> = WriteLoopData<I, ServerInner>;
type ServerCommandLoop = CommandLoopData<ServerInner>;

enum ServerToWriteMessage {
    ResponsePart(StreamId, HttpStreamPart),
    // send when user provided handler completed the stream
    ResponseStreamEnd(StreamId, ErrorCode),
    Common(CommonToWriteMessage),
}

enum ServerCommandMessage {
    DumpState(futures::sync::oneshot::Sender<ConnectionStateSnapshot>),
}

impl<I : AsyncWrite + Send> ServerWriteLoop<I> {
    fn _loop_handle(&self) -> reactor::Handle {
        self.inner.with(move |inner: &mut ServerInner| inner.common.loop_handle.clone())
    }

    fn process_response_part(self, stream_id: StreamId, part: HttpStreamPart) -> HttpFuture<Self> {
        let stream_id = self.inner.with(move |inner: &mut ServerInner| {
            let stream = inner.common.streams.get_mut(stream_id);
            if let Some(stream) = stream {
                if !stream.common.state.is_closed_local() {
                    stream.common.outgoing.push_back(part.content);
                    if part.last {
                        stream.common.outgoing_end = Some(ErrorCode::NoError);
                    }
                    Some(stream_id)
                } else {
                    None
                }
            } else {
                None
            }
        });
        if let Some(stream_id) = stream_id {
            self.send_outg_stream(stream_id)
        } else {
            Box::new(futures::finished(self))
        }
    }

    fn process_response_end(self, stream_id: StreamId, error_code: ErrorCode) -> HttpFuture<Self> {
        let stream_id = self.inner.with(move |inner: &mut ServerInner| {
            let stream = inner.common.streams.get_mut(stream_id);
            if let Some(stream) = stream {
                if stream.common.outgoing_end.is_none() {
                    stream.common.outgoing_end = Some(error_code);
                }
                Some(stream_id)
            } else {
                None
            }
        });
        if let Some(stream_id) = stream_id {
            self.send_outg_stream(stream_id)
        } else {
            Box::new(futures::finished(self))
        }
    }

    fn process_message(self, message: ServerToWriteMessage) -> HttpFuture<Self> {
        match message {
            ServerToWriteMessage::ResponsePart(stream_id, response) => {
                self.process_response_part(stream_id, response)
            },
            ServerToWriteMessage::ResponseStreamEnd(stream_id, error_code) => {
                self.process_response_end(stream_id, error_code)
            },
            ServerToWriteMessage::Common(common) => {
                self.process_common(common)
            },
        }
    }

    fn run(self, requests: HttpFutureStream<ServerToWriteMessage>) -> HttpFuture<()> {
        let requests = requests.map_err(Error::from);
        Box::new(requests
            .fold(self, move |wl, message: ServerToWriteMessage| {
                wl.process_message(message)
            })
            .map(|_| ()))
    }
}

impl ServerCommandLoop {
    fn process_dump_state(self, sender: futures::sync::oneshot::Sender<ConnectionStateSnapshot>) -> HttpFuture<Self> {
        // ignore send error, client might be already dead
        drop(sender.send(self.inner.with(|inner| inner.common.dump_state())));
        Box::new(futures::finished(self))
    }

    fn process_message(self, message: ServerCommandMessage) -> HttpFuture<Self> {
        match message {
            ServerCommandMessage::DumpState(sender) => self.process_dump_state(sender),
        }
    }

    fn run(self, requests: HttpFutureStreamSend<ServerCommandMessage>) -> HttpFuture<()> {
        let requests = requests.map_err(Error::from);
        Box::new(requests
            .fold(self, move |l, message: ServerCommandMessage| {
                l.process_message(message)
            })
            .map(|_| ()))
    }}

pub struct ServerConnection {
    command_tx: futures::sync::mpsc::UnboundedSender<ServerCommandMessage>,
}

impl ServerConnection {
    fn connected<F, I>(lh: &reactor::Handle, socket: HttpFutureSend<I>, _conf: ServerConf, service: Arc<F>)
                       -> (ServerConnection, HttpFuture<()>)
        where
            F : Service,
            I : AsyncRead + AsyncWrite + Send + 'static,
    {
        let lh = lh.clone();

        let (to_write_tx, to_write_rx) = futures::sync::mpsc::unbounded::<ServerToWriteMessage>();
        let (command_tx, command_rx) = futures::sync::mpsc::unbounded::<ServerCommandMessage>();

        let to_write_rx = to_write_rx.map_err(|()| Error::IoError(io::Error::new(io::ErrorKind::Other, "to_write")));
        let command_rx = Box::new(command_rx.map_err(|()| Error::IoError(io::Error::new(io::ErrorKind::Other, "command"))));

        let handshake = socket.and_then(server_handshake);

        let run = handshake.and_then(move |socket| {
            let (read, write) = socket.split();

            let inner = TaskRcMut::new(ServerInner {
                common: LoopInnerCommon::new(lh),
                factory: service,
                to_write_tx: to_write_tx.clone(),

            });

            let run_write = ServerWriteLoop { write: write, inner: inner.clone() }.run(Box::new(to_write_rx));
            let run_read = ServerReadLoop { read: read, inner: inner.clone() }.run();
            let run_command = ServerCommandLoop { inner: inner.clone() }.run(command_rx);

            run_write.join(run_read).join(run_command).map(|_| ())
        });

        let future = Box::new(run.then(|x| { info!("connection end: {:?}", x); x }));

        (ServerConnection {
            command_tx: command_tx,
        }, future)
    }

    pub fn new<S>(lh: &reactor::Handle, socket: TcpStream, tls: ServerTlsOption, conf: ServerConf, service: Arc<S>)
                  -> (ServerConnection, HttpFuture<()>)
        where
            S : Service,
    {
        match tls {
            ServerTlsOption::Plain =>
                ServerConnection::connected(
                    lh, Box::new(futures::finished(socket)), conf, service),
            ServerTlsOption::Tls(acceptor) =>
                ServerConnection::connected(
                    lh, Box::new(acceptor.accept_async(socket).map_err(Error::from)), conf, service),
        }
    }

    pub fn new_plain<S>(lh: &reactor::Handle, socket: TcpStream, conf: ServerConf, service: Arc<S>)
                        -> (ServerConnection, HttpFuture<()>)
        where
            S : Service,
    {
        ServerConnection::new(lh, socket, ServerTlsOption::Plain, conf, service)
    }

    pub fn new_plain_fn<F>(lh: &reactor::Handle, socket: TcpStream, conf: ServerConf, f: F)
                           -> (ServerConnection, HttpFuture<()>)
        where
            F : Fn(Headers, HttpPartStream) -> Response + Send + 'static,
    {
        struct HttpServiceFn<F>(F);

        impl<F> Service for HttpServiceFn<F>
            where F : Fn(Headers, HttpPartStream) -> Response + Send + 'static
        {
            fn start_request(&self, headers: Headers, req: HttpPartStream) -> Response {
                (self.0)(headers, req)
            }
        }

        ServerConnection::new_plain(lh, socket, conf, Arc::new(HttpServiceFn(f)))
    }

    /// For tests
    pub fn dump_state(&self) -> HttpFutureSend<ConnectionStateSnapshot> {
        let (tx, rx) = futures::oneshot();

        self.command_tx.clone().send(ServerCommandMessage::DumpState(tx))
            .expect("send request to dump state");

        let rx = rx.map_err(|_| Error::from(io::Error::new(io::ErrorKind::Other, "oneshot canceled")));

        Box::new(rx)
    }

}
<|endoftext|>


<commit_before>//! Definition of the `SelectOk` combinator, finding the first successful future
//! in a list.

use std::mem;
use std::prelude::v1::*;

use {Future, IntoFuture, Poll, Async};

/// Future for the `select_ok` combinator, waiting for one of any of a list of
/// futures to succesfully complete. unlike `select_all`, this future ignores all
/// but the last error, if there are any.
///
/// This is created by the `select_ok` function.
#[must_use = "futures do nothing unless polled"]
pub struct SelectOk<A> where A: Future {
    inner: Vec<A>,
}

/// Creates a new future which will select the first successful future over a list of futures.
///
/// The returned future will wait for any future within `iter` to be ready and Ok. Unlike
/// select_all, this will only return the first successful completion, or the last
/// failure. This is useful in contexts where any success is desired and failures
/// are ignored, unless all the futures fail.
///
/// # Panics
///
/// This function will panic if the iterator specified contains no items.
pub fn select_ok<I>(iter: I) -> SelectOk<<I::Item as IntoFuture>::Future>
    where I: IntoIterator,
          I::Item: IntoFuture,
{
    let ret = SelectOk {
        inner: iter.into_iter()
                   .map(|a| a.into_future())
                   .collect(),
    };
    assert!(ret.inner.len() > 0);
    ret
}

impl<A> Future for SelectOk<A> where A: Future {
    type Item = (A::Item, Vec<A>);
    type Error = A::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        // loop until we've either exhausted all errors, a success was hit, or nothing is ready
        loop {
            let item = self.inner.iter_mut().enumerate().filter_map(|(i, f)| {
                match f.poll() {
                    Ok(Async::NotReady) => None,
                    Ok(Async::Ready(e)) => Some((i, Ok(e))),
                    Err(e) => Some((i, Err(e))),
                }
            }).next();

            match item {
                Some((idx, res)) => {
                    // always remove Ok or Err, if it's not the last Err continue looping
                    drop(self.inner.remove(idx));
                    match res {
                        Ok(e) => {
                            let rest = mem::replace(&mut self.inner, Vec::new());
                            return Ok(Async::Ready((e, rest)))
                        },
                        Err(e) => {
                            if self.inner.is_empty() {
                                return Err(e)
                            }
                        },
                    }
                }
                None => {
                    // based on the filter above, nothing is ready, return
                    return Ok(Async::NotReady)
                },
            }
        }
    }
}
<commit_msg>Fixed formatting of a function name<commit_after>//! Definition of the `SelectOk` combinator, finding the first successful future
//! in a list.

use std::mem;
use std::prelude::v1::*;

use {Future, IntoFuture, Poll, Async};

/// Future for the `select_ok` combinator, waiting for one of any of a list of
/// futures to succesfully complete. unlike `select_all`, this future ignores all
/// but the last error, if there are any.
///
/// This is created by the `select_ok` function.
#[must_use = "futures do nothing unless polled"]
pub struct SelectOk<A> where A: Future {
    inner: Vec<A>,
}

/// Creates a new future which will select the first successful future over a list of futures.
///
/// The returned future will wait for any future within `iter` to be ready and Ok. Unlike
/// `select_all`, this will only return the first successful completion, or the last
/// failure. This is useful in contexts where any success is desired and failures
/// are ignored, unless all the futures fail.
///
/// # Panics
///
/// This function will panic if the iterator specified contains no items.
pub fn select_ok<I>(iter: I) -> SelectOk<<I::Item as IntoFuture>::Future>
    where I: IntoIterator,
          I::Item: IntoFuture,
{
    let ret = SelectOk {
        inner: iter.into_iter()
                   .map(|a| a.into_future())
                   .collect(),
    };
    assert!(ret.inner.len() > 0);
    ret
}

impl<A> Future for SelectOk<A> where A: Future {
    type Item = (A::Item, Vec<A>);
    type Error = A::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        // loop until we've either exhausted all errors, a success was hit, or nothing is ready
        loop {
            let item = self.inner.iter_mut().enumerate().filter_map(|(i, f)| {
                match f.poll() {
                    Ok(Async::NotReady) => None,
                    Ok(Async::Ready(e)) => Some((i, Ok(e))),
                    Err(e) => Some((i, Err(e))),
                }
            }).next();

            match item {
                Some((idx, res)) => {
                    // always remove Ok or Err, if it's not the last Err continue looping
                    drop(self.inner.remove(idx));
                    match res {
                        Ok(e) => {
                            let rest = mem::replace(&mut self.inner, Vec::new());
                            return Ok(Async::Ready((e, rest)))
                        },
                        Err(e) => {
                            if self.inner.is_empty() {
                                return Err(e)
                            }
                        },
                    }
                }
                None => {
                    // based on the filter above, nothing is ready, return
                    return Ok(Async::NotReady)
                },
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add tests and documentation<commit_after><|endoftext|>


<commit_before>use std::fs::File;
use std::io::prelude::*;
use std::collections::HashMap;

#[derive(Debug, Clone, Copy)]
enum Direction {
  Left,
  Right,
  Up,
  Down
}

type Wire = Vec<(Direction, usize)>;
type Grid = HashMap<(i32, i32), HashMap<usize, usize>>;

fn get_input() -> std::io::Result<String> {
  let mut file = File::open("03.txt")?;
  let mut contents = String::new();
  file.read_to_string(&mut contents)?;

  Ok(contents)
}

fn norm((x, y): (i32, i32)) -> i32 {
  x.abs() + y.abs()
}

fn parse_wires(input: &str) -> Vec<Wire> {
  input.lines()
  .map(|line| {
    line.split(',')
    .filter_map(|token| {
      if token.len() < 2 {
        return None;
      }

      let steps = token.get(1..).and_then(|steps| steps.parse::<usize>().ok());
      let direction = match token.chars().nth(0) {
        Some('L') => Some(Direction::Left),
        Some('R') => Some(Direction::Right),
        Some('U') => Some(Direction::Up),
        Some('D') => Some(Direction::Down),
        _ => None
      };

      match (direction, steps) {
        (Some(direction), Some(steps)) => Some((direction, steps)),
        _ => None
      }
    })
    .collect::<Vec<_>>()
  })
  .collect::<Vec<_>>()
}

fn trace_wire(grid: &mut Grid, id: usize, wire: &Wire) {
  let mut position = (0, 0);
  let mut timestamp = 0;

  for &(direction, steps) in wire.iter() {
    let move_vector = match direction {
      Direction::Left => (-1, 0),
      Direction::Right => (1, 0),
      Direction::Up => (0, 1),
      Direction::Down => (0, -1)
    };

    for _ in 0..steps {
      position = (position.0 + move_vector.0, position.1 + move_vector.1);
      timestamp += 1;

      if !grid.contains_key(&position) {
        grid.insert(position, HashMap::new());
      }

      let ids = grid.get_mut(&position).unwrap();

      if !ids.contains_key(&id) {
        ids.insert(id, timestamp);
      }
    }
  }
}

fn iter_collisions(grid: &Grid) -> impl Iterator<Item = (i32, i32)> + '_ {
  grid.iter()
  .filter(|(_, ids)| ids.len() > 1)
  .map(|(&pos, _)| pos)
}

fn iter_collision_times(grid: &Grid) -> impl Iterator<Item = usize> + '_ {
  iter_collisions(grid)
  .map(move |pos| {
    grid.get(&pos)
    .unwrap()
    .values()
    .sum()
  })
}

fn main() {
  let input = get_input().unwrap();
  let wires = parse_wires(&input);
  let mut grid = Grid::new();

  for (i, wire) in wires.iter().enumerate() {
    trace_wire(&mut grid, i, wire);
  }

  iter_collisions(&grid)
  .map(|pos| norm(pos))
  .min()
  .map(|min_collision_norm| {
    println!("Part 1: {}", min_collision_norm);
  });

  iter_collision_times(&grid)
  .min()
  .map(|min_collision_time| {
    println!("Part 2: {}", min_collision_time);
  });
}
<commit_msg>Simplify code 2<commit_after>use std::fs::File;
use std::io::prelude::*;
use std::collections::HashMap;

#[derive(Debug, Clone, Copy)]
enum Direction {
  Left,
  Right,
  Up,
  Down
}

type Wire = Vec<(Direction, usize)>;
type Grid = HashMap<(i32, i32), HashMap<usize, usize>>;

fn get_input() -> std::io::Result<String> {
  let mut file = File::open("03.txt")?;
  let mut contents = String::new();
  file.read_to_string(&mut contents)?;

  Ok(contents)
}

fn norm((x, y): (i32, i32)) -> i32 {
  x.abs() + y.abs()
}

fn parse_wires(input: &str) -> Vec<Wire> {
  input.lines()
  .map(|line| {
    line.split(',')
    .filter_map(|token| {
      let steps = token.get(1..).and_then(|steps| steps.parse::<usize>().ok());
      let direction = match token.chars().nth(0) {
        Some('L') => Some(Direction::Left),
        Some('R') => Some(Direction::Right),
        Some('U') => Some(Direction::Up),
        Some('D') => Some(Direction::Down),
        _ => None
      };

      match (direction, steps) {
        (Some(direction), Some(steps)) => Some((direction, steps)),
        _ => None
      }
    })
    .collect::<Vec<_>>()
  })
  .collect::<Vec<_>>()
}

fn trace_wire(grid: &mut Grid, id: usize, wire: &Wire) {
  let mut position = (0, 0);
  let mut timestamp = 0;

  for &(direction, steps) in wire.iter() {
    let move_vector = match direction {
      Direction::Left => (-1, 0),
      Direction::Right => (1, 0),
      Direction::Up => (0, 1),
      Direction::Down => (0, -1)
    };

    for _ in 0..steps {
      position = (position.0 + move_vector.0, position.1 + move_vector.1);
      timestamp += 1;

      if !grid.contains_key(&position) {
        grid.insert(position, HashMap::new());
      }

      let ids = grid.get_mut(&position).unwrap();

      if !ids.contains_key(&id) {
        ids.insert(id, timestamp);
      }
    }
  }
}

fn iter_collisions(grid: &Grid) -> impl Iterator<Item = (i32, i32)> + '_ {
  grid.iter()
  .filter(|(_, ids)| ids.len() > 1)
  .map(|(&pos, _)| pos)
}

fn iter_collision_times(grid: &Grid) -> impl Iterator<Item = usize> + '_ {
  iter_collisions(grid)
  .map(move |pos| {
    grid.get(&pos)
    .unwrap()
    .values()
    .sum()
  })
}

fn main() {
  let input = get_input().unwrap();
  let wires = parse_wires(&input);
  let mut grid = Grid::new();

  for (i, wire) in wires.iter().enumerate() {
    trace_wire(&mut grid, i, wire);
  }

  iter_collisions(&grid)
  .map(|pos| norm(pos))
  .min()
  .map(|min_collision_norm| {
    println!("Part 1: {}", min_collision_norm);
  });

  iter_collision_times(&grid)
  .min()
  .map(|min_collision_time| {
    println!("Part 2: {}", min_collision_time);
  });
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate regex;

use regex::Regex;
use clap::{App,Arg};

fn main() {
    let args = App::new("grep-lite")
        .version("0.1")
        .about("searches for patterns")
        .arg(Arg::with_name("pattern")
             .help("the pattern to search for")
             .takes_value(true)
             .required(true))
        .get_matches();

    let pattern = args.value_of("pattern").unwrap();
    let re = Regex::new(pattern).unwrap();

    // PARAMETERS
    let context_lines = 2;
    let needle = "oo";
    let haystack = "Every face, every shop,
    bedroom window, public-house, and
    dark square is a picture
    feverishly turned--in search of what?
    It is the same with books.
    what do we seek
    through millions of pages?";

    // INITIALIZATINO
    let mut tags: Vec<usize> = Vec::new();
    let mut ctx: Vec<Vec<(usize, String)>> = Vec::new();

    // PASS 1
    for (i, line) in haystack.lines().enumerate() {
        if line.contains(needle) {
            tags.push(i);

            let v = Vec::with_capacity(2*context_lines + 1);
            ctx.push(v)
        }
    }

    if tags.len() == 0 {
        return;
    }

    // PASS 2
    for (i, line) in haystack.lines().enumerate() {
        for (j, tag) in tags.iter().enumerate() {
            let lower_bound = tag.saturating_sub(context_lines);
            let upper_bound = tag + context_lines;

            if (i >= lower_bound) && (i <= upper_bound) {
                let line_as_string = String::from(line);
                let local_ctx = (i, line_as_string);
                ctx[j].push(local_ctx);
            }
        }
    }

    // OUTPUT
    for local_ctx in ctx.iter() {
        for &(i, ref line) in local_ctx.iter() {
            let line_num = i + 1;
            println!("{}: {}", line_num, line);
        }
    }
    println!();

    let quote = "Every face, every shop, bedroom window, public-house, and
    dark square is a picture feverishly turned--in search of what?
    It is the same with books. What do we seek through millions of pages?";

    for (idx, line) in quote.lines().enumerate() {
        match re.find(line) {
            Some(_) => {
                let line_num = idx + 1;
                println!("{}: {}", line_num, line)
            },
            None => (),
        }
    }
}
<commit_msg>reading line by line from a file via a BufReader<commit_after>extern crate clap;
extern crate regex;

use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;

use regex::Regex;
use clap::{App,Arg};

fn main() {
    let args = App::new("grep-lite")
        .version("0.1")
        .about("searches for patterns")
        .arg(Arg::with_name("pattern")
             .help("the pattern to search for")
             .takes_value(true)
             .required(true))
        .arg(Arg::with_name("input")
             .help("File to search")
             .takes_value(true)
             .required(true))
        .get_matches();

    let pattern = args.value_of("pattern").unwrap();
    let re = Regex::new(pattern).unwrap();

    let input = args.value_of("input").unwrap();
    let f = File::open(input).unwrap();
    let mut reader = BufReader::new(f);

    // PARAMETERS
    let context_lines = 2;
    let needle = "oo";
    let haystack = "Every face, every shop,
    bedroom window, public-house, and
    dark square is a picture
    feverishly turned--in search of what?
    It is the same with books.
    what do we seek
    through millions of pages?";

    // INITIALIZATINO
    let mut tags: Vec<usize> = Vec::new();
    let mut ctx: Vec<Vec<(usize, String)>> = Vec::new();

    // PASS 1
    for (i, line) in haystack.lines().enumerate() {
        if line.contains(needle) {
            tags.push(i);

            let v = Vec::with_capacity(2*context_lines + 1);
            ctx.push(v)
        }
    }

    if tags.len() == 0 {
        return;
    }

    // PASS 2
    for (i, line) in haystack.lines().enumerate() {
        for (j, tag) in tags.iter().enumerate() {
            let lower_bound = tag.saturating_sub(context_lines);
            let upper_bound = tag + context_lines;

            if (i >= lower_bound) && (i <= upper_bound) {
                let line_as_string = String::from(line);
                let local_ctx = (i, line_as_string);
                ctx[j].push(local_ctx);
            }
        }
    }

    // OUTPUT
    for local_ctx in ctx.iter() {
        for &(i, ref line) in local_ctx.iter() {
            let line_num = i + 1;
            println!("{}: {}", line_num, line);
        }
    }
    println!();

    let mut line = String::new();
    let mut idx = 0;
    loop {
        let len = reader.read_line(&mut line).unwrap();
        if len == 0 {
            break
        }

        match re.find(&line) {
            Some(_) => {
                let line_num = idx + 1;
                println!("{}: {}", line_num, line);
                println!("{} ({} bytes long)", line, len);
            },
            None => (),
        }

        line.truncate(0);
        idx = idx + 1;
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use app_units::Au;
use webrender_traits::{FontKey, FontRenderMode, GlyphDimensions};
use webrender_traits::{NativeFontHandle, GlyphOptions};
use webrender_traits::{GlyphKey};

use freetype::freetype::{FT_Render_Mode, FT_Pixel_Mode};
use freetype::freetype::{FT_Done_FreeType, FT_Library_SetLcdFilter};
use freetype::freetype::{FT_Library, FT_Set_Char_Size};
use freetype::freetype::{FT_Face, FT_Long, FT_UInt, FT_F26Dot6};
use freetype::freetype::{FT_Init_FreeType, FT_Load_Glyph, FT_Render_Glyph};
use freetype::freetype::{FT_New_Memory_Face, FT_GlyphSlot, FT_LcdFilter};
use freetype::freetype::{FT_Done_Face};

use std::{mem, ptr, slice};
use std::collections::HashMap;

struct Face {
    face: FT_Face,
}

pub struct FontContext {
    lib: FT_Library,
    faces: HashMap<FontKey, Face>,
}

pub struct RasterizedGlyph {
    pub width: u32,
    pub height: u32,
    pub bytes: Vec<u8>,
}

fn float_to_fixed(before: usize, f: f64) -> i32 {
    ((1i32 << before) as f64 * f) as i32
}

fn float_to_fixed_ft(f: f64) -> i32 {
    float_to_fixed(6, f)
}

impl FontContext {
    pub fn new() -> FontContext {
        let mut lib: FT_Library = ptr::null_mut();
        unsafe {
            let result = FT_Init_FreeType(&mut lib);
            assert!(result.succeeded(), "Unable to initialize FreeType library {:?}", result);

            // TODO(gw): Check result of this to determine if freetype build supports subpixel.
            let result = FT_Library_SetLcdFilter(lib, FT_LcdFilter::FT_LCD_FILTER_DEFAULT);
            if !result.succeeded() {
                println!("WARN: Initializing a FreeType library build without subpixel AA enabled!");
            }
        }

        FontContext {
            lib: lib,
            faces: HashMap::new(),
        }
    }

    pub fn add_raw_font(&mut self, font_key: &FontKey, bytes: &[u8], index: u32) {
        if !self.faces.contains_key(&font_key) {
            let mut face: FT_Face = ptr::null_mut();
            let result = unsafe {
                FT_New_Memory_Face(self.lib,
                                   bytes.as_ptr(),
                                   bytes.len() as FT_Long,
                                   index as FT_Long,
                                   &mut face)
            };
            if result.succeeded() && !face.is_null() {
                self.faces.insert(*font_key, Face {
                    face: face,
                    //_bytes: bytes
                });
            } else {
                println!("WARN: webrender failed to load font {:?}", font_key);
            }
        }
    }

    pub fn add_native_font(&mut self, _font_key: &FontKey, _native_font_handle: NativeFontHandle) {
        panic!("TODO: Not supported on Linux");
    }

    pub fn delete_font(&mut self, font_key: &FontKey) {
        if let Some(face) = self.faces.remove(font_key) {
            let result = unsafe {
                FT_Done_Face(face.face)
            };
            assert!(result.succeeded());
        }
    }

    fn load_glyph(&self,
                  font_key: FontKey,
                  size: Au,
                  character: u32) -> Option<FT_GlyphSlot> {
        debug_assert!(self.faces.contains_key(&font_key));
        let face = self.faces.get(&font_key).unwrap();

        unsafe {
            let char_size = float_to_fixed_ft(size.to_f64_px());
            let result = FT_Set_Char_Size(face.face, char_size as FT_F26Dot6, 0, 0, 0);
            assert!(result.succeeded());

            let result =  FT_Load_Glyph(face.face, character as FT_UInt, 0);
            if result.succeeded() {
                let void_glyph = (*face.face).glyph;
                let slot_ptr: FT_GlyphSlot = mem::transmute(void_glyph);
                assert!(!slot_ptr.is_null());
                return Some(slot_ptr);
            }
        }

        None
    }

     pub fn get_glyph_dimensions(&mut self,
                                 key: &GlyphKey) -> Option<GlyphDimensions> {
        self.load_glyph(key.font_key, key.size, key.index).and_then(|slot| {
            let metrics = unsafe { &(*slot).metrics };
            if metrics.width == 0 || metrics.height == 0 {
                None
            } else {
                Some(GlyphDimensions {
                    left: (metrics.horiBearingX >> 6) as i32,
                    top: (metrics.horiBearingY >> 6) as i32,
                    width: (metrics.width >> 6) as u32,
                    height: (metrics.height >> 6) as u32,
                })
            }
        })
    }

    pub fn rasterize_glyph(&mut self,
                           key: &GlyphKey,
                           render_mode: FontRenderMode,
                           _glyph_options: Option<GlyphOptions>)
                           -> Option<RasterizedGlyph> {

        let slot = match self.load_glyph(key.font_key, key.size, key.index) {
            Some(slot) => slot,
            None => return None,
        };
        let render_mode = match render_mode {
            FontRenderMode::Mono => FT_Render_Mode::FT_RENDER_MODE_MONO,
            FontRenderMode::Alpha => FT_Render_Mode::FT_RENDER_MODE_NORMAL,
            FontRenderMode::Subpixel => FT_Render_Mode::FT_RENDER_MODE_LCD,
        };

        let result = unsafe { FT_Render_Glyph(slot, render_mode) };
        if !result.succeeded() {
            error!("Unable to rasterize {:?} with {:?}", key, render_mode);
            return None;
        }

        let bitmap = unsafe { &(*slot).bitmap };
        let metrics = unsafe { &(*slot).metrics };
        let glyph_width = (metrics.width >> 6) as i32;
        let glyph_height = (metrics.height >> 6) as i32;
        let mut final_buffer = Vec::with_capacity(glyph_width as usize *
                                                  glyph_height as usize *
                                                  4);

        if bitmap.pixel_mode == FT_Pixel_Mode::FT_PIXEL_MODE_MONO as u8 {
            // This is not exactly efficient... but it's only used by the
            // reftest pass when we have AA disabled on glyphs.
            let offset_x = unsafe { (metrics.horiBearingX >> 6) as i32 - (*slot).bitmap_left };
            let offset_y = unsafe { (metrics.horiBearingY >> 6) as i32 - (*slot).bitmap_top };

            // Due to AA being disabled, the bitmap produced for mono
            // glyphs is often smaller than the reported glyph dimensions.
            // To account for this, place the rendered glyph within the
            // box of the glyph dimensions, filling in invalid pixels with
            // zero alpha.
            for iy in 0..glyph_height {
                let y = iy - offset_y;
                for ix in 0..glyph_width {
                    let x = ix + offset_x;
                    let valid_byte = x >= 0 &&
                        y >= 0 &&
                        x < bitmap.width as i32 &&
                        y < bitmap.rows as i32;
                    let byte_value = if valid_byte {
                        let byte_index = (y * bitmap.pitch as i32) + (x >> 3);
                        let bit_index = x & 7;
                        let byte = unsafe {
                            *bitmap.buffer.offset(byte_index as isize)
                        };
                        if byte & (0x80 >> bit_index) != 0 {
                            0xff
                        } else {
                            0
                        }
                    } else {
                        0
                    };

                    final_buffer.extend_from_slice(&[ 0xff, 0xff, 0xff, byte_value ]);
                }
            }
        } else if bitmap.pixel_mode == FT_Pixel_Mode::FT_PIXEL_MODE_GRAY as u8 {
            // We can assume that the reported glyph dimensions exactly
            // match the rasterized bitmap for normal alpha coverage glyphs.

            let buffer = unsafe {
                slice::from_raw_parts(
                    bitmap.buffer,
                    (bitmap.width * bitmap.rows) as usize
                )
            };

            // Convert to RGBA.
            for &byte in buffer.iter() {
                final_buffer.extend_from_slice(&[ 0xff, 0xff, 0xff, byte ]);
            }
        } else if bitmap.pixel_mode == FT_Pixel_Mode::FT_PIXEL_MODE_LCD as u8 {
            if bitmap.width % 3 != 0 {
                error!("Unexpected bitmap width for LCD mode: {}", bitmap.width);
            }
            for y in 0..bitmap.rows {
                for x in 0..(bitmap.width / 3) {
                    let index = (y as i32 * bitmap.pitch) + (x as i32 * 3);
                    let (b, g, r) = unsafe {
                        let ptr = bitmap.buffer.offset(index as isize);
                        (*ptr, *ptr.offset(1), *ptr.offset(2))
                    };

                    final_buffer.extend_from_slice(&[r, g, b, 0xff]);
                }
            }
        } else {
            panic!("Unexpected render mode: {}!", bitmap.pixel_mode);
        }

        Some(RasterizedGlyph {
            width: glyph_width as u32,
            height: glyph_height as u32,
            bytes: final_buffer,
        })
    }
}

impl Drop for FontContext {
    fn drop(&mut self) {
        unsafe {
            FT_Done_FreeType(self.lib);
        }
    }
}
<commit_msg>UNIX font rendering with FreeType is re-implemented<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use app_units::Au;
use webrender_traits::{FontKey, FontRenderMode, GlyphDimensions};
use webrender_traits::{NativeFontHandle, GlyphOptions};
use webrender_traits::{GlyphKey};

use freetype::freetype::{FT_Render_Mode, FT_Pixel_Mode};
use freetype::freetype::{FT_Done_FreeType, FT_Library_SetLcdFilter};
use freetype::freetype::{FT_Library, FT_Set_Char_Size};
use freetype::freetype::{FT_Face, FT_Long, FT_UInt, FT_F26Dot6};
use freetype::freetype::{FT_Init_FreeType, FT_Load_Glyph, FT_Render_Glyph};
use freetype::freetype::{FT_New_Memory_Face, FT_GlyphSlot, FT_LcdFilter};
use freetype::freetype::{FT_Done_Face, FT_Error};

use std::{cmp, mem, ptr, slice};
use std::collections::HashMap;

struct Face {
    face: FT_Face,
}

pub struct FontContext {
    lib: FT_Library,
    faces: HashMap<FontKey, Face>,
}

pub struct RasterizedGlyph {
    pub width: u32,
    pub height: u32,
    pub bytes: Vec<u8>,
}

fn float_to_fixed(before: usize, f: f64) -> i32 {
    ((1i32 << before) as f64 * f) as i32
}

fn float_to_fixed_ft(f: f64) -> i32 {
    float_to_fixed(6, f)
}

const SUCCESS: FT_Error = FT_Error(0);

impl FontContext {
    pub fn new() -> FontContext {
        let mut lib: FT_Library = ptr::null_mut();
        unsafe {
            let result = FT_Init_FreeType(&mut lib);
            assert!(result.succeeded(), "Unable to initialize FreeType library {:?}", result);

            // TODO(gw): Check result of this to determine if freetype build supports subpixel.
            let result = FT_Library_SetLcdFilter(lib, FT_LcdFilter::FT_LCD_FILTER_DEFAULT);
            if !result.succeeded() {
                println!("WARN: Initializing a FreeType library build without subpixel AA enabled!");
            }
        }

        FontContext {
            lib: lib,
            faces: HashMap::new(),
        }
    }

    pub fn add_raw_font(&mut self, font_key: &FontKey, bytes: &[u8], index: u32) {
        if !self.faces.contains_key(&font_key) {
            let mut face: FT_Face = ptr::null_mut();
            let result = unsafe {
                FT_New_Memory_Face(self.lib,
                                   bytes.as_ptr(),
                                   bytes.len() as FT_Long,
                                   index as FT_Long,
                                   &mut face)
            };
            if result.succeeded() && !face.is_null() {
                self.faces.insert(*font_key, Face {
                    face: face,
                    //_bytes: bytes
                });
            } else {
                println!("WARN: webrender failed to load font {:?}", font_key);
            }
        }
    }

    pub fn add_native_font(&mut self, _font_key: &FontKey, _native_font_handle: NativeFontHandle) {
        panic!("TODO: Not supported on Linux");
    }

    pub fn delete_font(&mut self, font_key: &FontKey) {
        if let Some(face) = self.faces.remove(font_key) {
            let result = unsafe {
                FT_Done_Face(face.face)
            };
            assert!(result.succeeded());
        }
    }

    fn load_glyph(&self,
                  font_key: FontKey,
                  size: Au,
                  character: u32) -> Option<FT_GlyphSlot> {

        debug_assert!(self.faces.contains_key(&font_key));
        let face = self.faces.get(&font_key).unwrap();
        let char_size = float_to_fixed_ft(size.to_f64_px());

        assert_eq!(SUCCESS, unsafe {
            FT_Set_Char_Size(face.face, char_size as FT_F26Dot6, 0, 0, 0)
        });

        let result = unsafe {
            FT_Load_Glyph(face.face, character as FT_UInt, 0)
        };

        if result == SUCCESS {
            let slot = unsafe { (*face.face).glyph };
            assert!(slot != ptr::null_mut());
            Some(slot)
        } else {
            error!("Unable to load glyph for {} of size {:?} from font {:?}, {:?}",
                character, size, font_key, result);
            None
        }
    }

    fn get_glyph_dimensions_impl(slot: FT_GlyphSlot) -> Option<GlyphDimensions> {
        let metrics = unsafe { &(*slot).metrics };
        if metrics.width == 0 || metrics.height == 0 {
            None
        } else {
            let left = metrics.horiBearingX >> 6;
            let top = metrics.horiBearingY >> 6;
            let right = (metrics.horiBearingX + metrics.width + 0x3f) >> 6;
            let bottom = (metrics.horiBearingY + metrics.height + 0x3f) >> 6;
            Some(GlyphDimensions {
                left: left as i32,
                top: top as i32,
                width: (right - left) as u32,
                height: (bottom - top) as u32,
            })
        }
    }

    pub fn get_glyph_dimensions(&mut self,
                                key: &GlyphKey) -> Option<GlyphDimensions> {
        self.load_glyph(key.font_key, key.size, key.index)
            .and_then(Self::get_glyph_dimensions_impl)
    }

    pub fn rasterize_glyph(&mut self,
                           key: &GlyphKey,
                           render_mode: FontRenderMode,
                           _glyph_options: Option<GlyphOptions>)
                           -> Option<RasterizedGlyph> {

        let slot = match self.load_glyph(key.font_key, key.size, key.index) {
            Some(slot) => slot,
            None => return None,
        };
        let render_mode = match render_mode {
            FontRenderMode::Mono => FT_Render_Mode::FT_RENDER_MODE_MONO,
            FontRenderMode::Alpha => FT_Render_Mode::FT_RENDER_MODE_NORMAL,
            FontRenderMode::Subpixel => FT_Render_Mode::FT_RENDER_MODE_LCD,
        };

        let result = unsafe { FT_Render_Glyph(slot, render_mode) };
        if result != SUCCESS {
            error!("Unable to rasterize {:?} with {:?}, {:?}", key, render_mode, result);
            return None;
        }

        let dimensions = Self::get_glyph_dimensions_impl(slot).unwrap();
        let bitmap = unsafe { &(*slot).bitmap };
        let pixel_mode = unsafe { mem::transmute(bitmap.pixel_mode as u32) };
        info!("Rasterizing {:?} as {:?} with dimensions {:?}", key, render_mode, dimensions);
        // we may be filling only a part of the buffer, so initialize the whole thing with 0
        let mut final_buffer = Vec::with_capacity(dimensions.width as usize *
                                                  dimensions.height as usize *
                                                  4);

        let offset_x = dimensions.left as i32 - unsafe { (*slot).bitmap_left };

        for y in 0 .. dimensions.height {
            let src_y = y as i32 + dimensions.top - unsafe { (*slot).bitmap_top };
            if src_y < 0 || src_y >= bitmap.rows as i32 {
                for _x in 0 .. dimensions.width {
                    final_buffer.extend_from_slice(&[0xff, 0xff, 0xff, 0]);
                }
                continue
            }
            let row = unsafe {
                let base = bitmap.buffer.offset((src_y * bitmap.pitch) as isize);
                slice::from_raw_parts(base, bitmap.width as usize)
            };
            match pixel_mode {
                FT_Pixel_Mode::FT_PIXEL_MODE_MONO => {
                    for x in 0 .. dimensions.width {
                        let src_x = x as i32 + offset_x;
                        let mask = 0x80 >> (src_x & 0x7);
                        let alpha = if src_x >= 0 && src_x < 8 * bitmap.width as i32 &&
                                       row[(src_x >> 3) as usize] & mask != 0 {
                            0xff
                        } else {
                            0
                        };
                        final_buffer.extend_from_slice(&[0xff, 0xff, 0xff, alpha]);
                    }
                }
                FT_Pixel_Mode::FT_PIXEL_MODE_GRAY => {
                    for _x in 0 .. -offset_x {
                        final_buffer.extend_from_slice(&[0xff, 0xff, 0xff, 0]);
                    }
                    let cut_length = cmp::max(0, (offset_x + dimensions.width as i32));
                    for &alpha in &row[.. cmp::min(row.len(), cut_length as usize)] {
                        final_buffer.extend_from_slice(&[0xff, 0xff, 0xff, alpha]);
                    }
                    for _x in bitmap.width as i32 - offset_x .. dimensions.width as i32 {
                        final_buffer.extend_from_slice(&[0xff, 0xff, 0xff, 0]);
                    }
                }
                FT_Pixel_Mode::FT_PIXEL_MODE_LCD => {
                    assert_eq!(bitmap.width % 3, 0);
                    for x in 0 .. dimensions.width {
                        let src_x = (x as i32 + offset_x) * 3;
                        let slice = if src_x >= 0 && src_x < bitmap.width as i32 {
                            let t = &row[src_x as usize ..];
                            [t[2], t[1], t[0], 0xff]
                        } else {
                            [0xff, 0xff, 0xff, 0]
                        };
                        final_buffer.extend_from_slice(&slice);
                    }
                }
                _ => panic!("Unsupported {:?}", pixel_mode)
            }
            assert_eq!(final_buffer.len(), ((y+1) * dimensions.width * 4) as usize);
        }

        Some(RasterizedGlyph {
            width: dimensions.width as u32,
            height: dimensions.height as u32,
            bytes: final_buffer,
        })
    }
}

impl Drop for FontContext {
    fn drop(&mut self) {
        unsafe {
            FT_Done_FreeType(self.lib);
        }
    }
}
<|endoftext|>


<commit_before>
use std::fmt::Debug;

pub fn insertion_sort<T: Debug + PartialOrd>(input: &Vec<T>) -> Vec<usize> /*&[T]*/ {
    let n = input.len();

    // let mut output_index: Vec<usize> = vec![0];
    let mut output_index: Vec<usize> = Vec::with_capacity(n);

    // Place the first element's index (0) as the first element of the output_index vector.
    output_index.push(0);

    println!("n = {:?}", n);
    println!("input:        {:?}", input);
    println!("output_index: {:?}", output_index);
    // println!("  output: {:?}", input[output[0]]);

    if n > 1 {
        // Loop over input vector, skipping the first element as it's already inserted as the first
        // element of output_index.
        for (i_start_at_0,elem) in input.iter().skip(1).enumerate() {
            let i = i_start_at_0 + 1;
            println!("  i={:?} Finding where to put element {:?} (i={:?}) in output_index: {:?}", i, elem, i, output_index);
            // println!("    0. input[i={}] == elem={:?}", i, elem);
            // println!("    0. output_index: {:?}", output_index);

            // let x: () = *elem;

            // println!("       *output_index.last().unwrap() = {:?}", *output_index.last().unwrap());
            // println!("       input[*output_index.last().unwrap()] = {:?}", input[*output_index.last().unwrap()]);

            // Verify next element if it is smaller
            // If next element is larger than the last stored index, just place that element at
            // the end.
            if *elem >= input[*output_index.last().unwrap()] {
                // Next element "elem" is already larger than the previous stored index.
                // Just use its index.
                output_index.push(i);

                println!("    1. Pushing element '{:?}' at the end.", elem);
            } else {
                println!("    2. elem ?< input[output_index[0]]");
                println!("           {:?} ?< {:?}", elem, input[output_index[0]]);
                // The next element of the input vector is smaller than the last stored on.
                // Let's find where it should go by looping back on the stored indices.
                // NOTE: we must use a loop on indices as to prevent problems with the borrow-checker.
                if *elem < input[output_index[0]] {
                    println!("        2a. Yes: --> putting i in front");
                    output_index.insert(0, i);
                } else {
                    println!("        2b. No: --> Looping back");
                    for j in (0..i).rev() {
                        println!("            j={:?}   elem={:?}   input[output_index[j]]={:?}", j, elem, input[output_index[j]]);
                        if *elem > input[output_index[j]] {
                            output_index.insert(j+1, i);
                            break;
                        }
                    }
                }
                println!("        3. output_index: {:?}", output_index);
            }

            print!("           output: [");
            for j in output_index.iter() {
                    print!("{:?}, ", input[*j]);
            }
            println!("]");
        }
    }

    println!("END: output_index: {:?}", output_index);
    print!("END: output: [");
    for j in output_index.iter() {
            print!("{:?}, ", input[*j]);
    }
    println!("]");

    assert_eq!(output_index.len(), n);

    return output_index;
}
<commit_msg>Cleanups<commit_after>
use std::fmt::Debug;

pub fn insertion_sort<T: Debug + PartialOrd>(input: &Vec<T>) -> Vec<usize> /*&[T]*/ {
    let n = input.len();

    let mut output_index: Vec<usize> = Vec::with_capacity(n);

    // Place the first element's index (0) as the first element of the output_index vector.
    output_index.push(0);

    println!("n = {:?}", n);
    println!("input:        {:?}", input);
    println!("output_index: {:?}", output_index);

    if n > 1 {
        // Loop over input vector, skipping the first element as it's already inserted as the first
        // element of output_index.
        for (i_start_at_0,elem) in input.iter().skip(1).enumerate() {
            let i = i_start_at_0 + 1;
            println!("  i={:?} Finding where to put element {:?} (i={:?}) in output_index: {:?}", i, elem, i, output_index);

            // Verify next element if it is smaller
            // If next element is larger than the last stored index, just place that element at
            // the end.
            if *elem >= input[*output_index.last().unwrap()] {
                // Next element "elem" is already larger than the previous stored index.
                // Just use its index.
                output_index.push(i);

                println!("    1. Pushing element '{:?}' at the end.", elem);
            } else {
                println!("    2. elem ?< input[output_index[0]]");
                println!("           {:?} ?< {:?}", elem, input[output_index[0]]);
                // The next element of the input vector is smaller than the last stored on.
                // Let's find where it should go by looping back on the stored indices.
                // NOTE: we must use a loop on indices as to prevent problems with the borrow-checker.
                if *elem < input[output_index[0]] {
                    println!("        2a. Yes: --> putting i in front");
                    output_index.insert(0, i);
                } else {
                    println!("        2b. No: --> Looping back");
                    for j in (0..i).rev() {
                        println!("            j={:?}   elem={:?}   input[output_index[j]]={:?}", j, elem, input[output_index[j]]);
                        if *elem > input[output_index[j]] {
                            output_index.insert(j+1, i);
                            break;
                        }
                    }
                }
                println!("        3. output_index: {:?}", output_index);
            }

            print!("           output: [");
            for j in output_index.iter() {
                    print!("{:?}, ", input[*j]);
            }
            println!("]");
        }
    }

    println!("END: output_index: {:?}", output_index);
    print!("END: output: [");
    for j in output_index.iter() {
            print!("{:?}, ", input[*j]);
    }
    println!("]");

    assert_eq!(output_index.len(), n);

    return output_index;
}
<|endoftext|>


<commit_before>use std::path::Path;
use git2::Repository;
use git2::ObjectType;
use git2::BranchType;
use rand::Rng;
use termion::color;
use rand;

use yaml_rust::yaml::Hash;
use yaml_rust::{Yaml, YamlEmitter};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct State {
    pub task: String,
    pub focus: String,
    pub filter: Option<Filter>,
    pub message: String,
    pub include: Vec<String>,
    pub property: Vec<Property>,
    pub diff: Vec<String>,
    pub save_update: Option<String>,
    pub new_task: Option<String>,
    pub dragged: Option<String>
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Property {
    pub name: String,
    pub value: String
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Filter {
    pub name: String,
    pub value: String
}

pub enum StateError {
}

impl State {

    pub fn blank() -> State {
        State {
            task: String::from("master"),
            focus: String::new(),
            message: String::new(),
            include: vec![],
            diff: vec![],
            property: vec![],
            save_update: None,
            new_task: None,
            filter: None,
            dragged: None
        }
    }

    pub fn reset(&mut self) {
        self.message = String::new();
        self.property = vec![];
        self.include = vec![];
        self.save_update = None;
        self.new_task = None;
    }

    pub fn reset_with_status(&mut self) {
        self.message = String::new();
        self.property = self.property.iter().filter_map(|p| if p.name == "Status" { Some(p.clone()) } else { None }).collect();
        self.include = vec![];
        self.save_update = None;
        self.new_task = None;
    }

    pub fn apply(&mut self, mut last_state: Option<State>, rng: &mut rand::ThreadRng) -> Result<State, StateError> {
        let new_last_state = self.clone();
        let repo = Repository::open_from_env().unwrap();
        if let Some(ref mut last) = last_state {
            println!("{}{:?}{}", color::Fg(color::LightBlack), last, color::Fg(color::Reset));
            println!("{:?}", self);
            println!("▶ ");
            println!("Applying to repo: {:?}", repo.path());
            if self.task != last.task {
                println!("  {}Task changing{}  {} => {}", color::Fg(color::LightYellow), color::Fg(color::Reset), last.task, self.task);
                if self.dragged.is_some() {
                    println!("  {}Saving last state due to dragging{}", color::Fg(color::LightGreen), color::Fg(color::Reset));
                    last.save_update(repo, rng);
                    self.reset_with_status();
                } else {
                    let switching_to_task = self.task.clone();
                    self.task = last.task.clone();
                    self.save_update(repo, rng);
                    self.task = switching_to_task;
                    self.reset();
                }
            } else {
                println!("  {}Updating task {}{}", color::Fg(color::LightGreen), self.task, color::Fg(color::Reset));
                //self.apply_index(&repo);

                if self.save_update.is_some() || self.new_task.is_some() {
                    self.save_update(repo, rng);
                    self.reset();
                }
            }
        } else {
            let head = repo.head().unwrap();
            let task = head.shorthand().unwrap();
            if self.task != task {
                println!("  Changing task with no last state, will reset");
                self.reset();
            }
        }
        Ok(new_last_state)
    }

    fn save_update(&mut self, repo: Repository, rng: &mut rand::ThreadRng) {
        let mut yaml = String::new();
        self.convert_to_yaml(&mut yaml);
        let message = format!("{}\n{}", self.message, yaml);

        let mut index = repo.index().unwrap();
        index.read(false).unwrap();
        let author = repo.signature().unwrap();
        let tree_oid = index.write_tree().unwrap();
        let tree = repo.find_tree(tree_oid).unwrap();

        let branch = repo.find_branch(&self.task, BranchType::Local);
        match branch {
            Ok(branch) => {
                let head = branch.into_reference();
                let commit = head.peel(ObjectType::Commit).unwrap();
                repo.commit(Some(&head.name().unwrap()), &author, &author, &message, &tree, &[&commit.as_commit().unwrap()]).unwrap();
            }
            Err(_) => {
                println!("Initial Commit");
                repo.commit(Some("refs/heads/master"), &author, &author, &message, &tree, &[]).unwrap();
            }
        };

        println!("  {}Saved changes to {}{} {:?}", color::Fg(color::LightRed), self.task, color::Fg(color::Reset), self);
        if self.new_task.is_some() {
            let num = rng.gen::<u16>();
            let new_task = format!("{:X}", num);
            println!("  {}Creating task {}{}", color::Fg(color::LightBlue), new_task, color::Fg(color::Reset));
            if let Ok(master_branch) = repo.find_branch("master", BranchType::Local) {
                let master = master_branch.into_reference();
                let commit_obj = master.peel(ObjectType::Commit).unwrap();
                let commit = commit_obj.as_commit().unwrap();
                repo.branch(&new_task, &commit, false).unwrap();
                self.task = new_task;
                self.reset();
            }
        }
    }

    // Constructing the properties YAML from State
    fn convert_to_yaml(&self, mut yaml: &mut String) {
        let mut tasks = Hash::new();
        let mut properties = Hash::new();
        let mut emitter = YamlEmitter::new(&mut yaml);
        for property in self.property.clone() {
            properties.insert(Yaml::String(property.name), Yaml::String(property.value));
        }
        tasks.insert(Yaml::String(self.task.clone()), Yaml::Hash(properties));
        emitter.dump(&Yaml::Hash(tasks)).unwrap();
    }

    fn apply_index(&self, repo: &Repository) {
        let branch = repo.find_branch(&self.task, BranchType::Local);
        let head = match branch {
            Ok(branch) => branch.into_reference(),
            _ => repo.head().unwrap()
        };
        let commit = head.peel(ObjectType::Commit).unwrap();
        let mut index = repo.index().unwrap();

        // apply git index changes only if task is the working directory
        if self.task == repo.head().unwrap().shorthand().unwrap() {
            let to_remove = index.iter().fold(vec![], |mut acc, entry| {
                let entry_path = String::from_utf8_lossy(entry.path.as_ref());
                match self.include.iter().find(|i| i.as_ref() == entry_path) {
                    None => acc.push(entry_path.into_owned()),
                    _ => {}
                };
                acc
            });
            repo.reset_default(Some(&commit), to_remove.iter()).unwrap();
            for change in &self.include {
                let path = Path::new(&change);
                index.add_path(path).unwrap();
            }
            index.write().unwrap();
        }
    }

}
<commit_msg>The last commit appears to have fixed the bug, I suspected the index of causing<commit_after>use std::path::Path;
use git2::Repository;
use git2::ObjectType;
use git2::BranchType;
use rand::Rng;
use termion::color;
use rand;

use yaml_rust::yaml::Hash;
use yaml_rust::{Yaml, YamlEmitter};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct State {
    pub task: String,
    pub focus: String,
    pub filter: Option<Filter>,
    pub message: String,
    pub include: Vec<String>,
    pub property: Vec<Property>,
    pub diff: Vec<String>,
    pub save_update: Option<String>,
    pub new_task: Option<String>,
    pub dragged: Option<String>
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Property {
    pub name: String,
    pub value: String
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Filter {
    pub name: String,
    pub value: String
}

pub enum StateError {
}

impl State {

    pub fn blank() -> State {
        State {
            task: String::from("master"),
            focus: String::new(),
            message: String::new(),
            include: vec![],
            diff: vec![],
            property: vec![],
            save_update: None,
            new_task: None,
            filter: None,
            dragged: None
        }
    }

    pub fn reset(&mut self) {
        self.message = String::new();
        self.property = vec![];
        self.include = vec![];
        self.save_update = None;
        self.new_task = None;
    }

    pub fn reset_with_status(&mut self) {
        self.message = String::new();
        self.property = self.property.iter().filter_map(|p| if p.name == "Status" { Some(p.clone()) } else { None }).collect();
        self.include = vec![];
        self.save_update = None;
        self.new_task = None;
    }

    pub fn apply(&mut self, mut last_state: Option<State>, rng: &mut rand::ThreadRng) -> Result<State, StateError> {
        let new_last_state = self.clone();
        let repo = Repository::open_from_env().unwrap();
        if let Some(ref mut last) = last_state {
            println!("{}{:?}{}", color::Fg(color::LightBlack), last, color::Fg(color::Reset));
            println!("{:?}", self);
            println!("▶ ");
            println!("Applying to repo: {:?}", repo.path());
            if self.task != last.task {
                println!("  {}Task changing{}  {} => {}", color::Fg(color::LightYellow), color::Fg(color::Reset), last.task, self.task);
                if self.dragged.is_some() {
                    println!("  {}Saving last state due to dragging{}", color::Fg(color::LightGreen), color::Fg(color::Reset));
                    last.save_update(repo, rng);
                    self.reset_with_status();
                } else {
                    let switching_to_task = self.task.clone();
                    self.task = last.task.clone();
                    self.save_update(repo, rng);
                    self.task = switching_to_task;
                    self.reset();
                }
            } else {
                println!("  {}Updating task {}{}", color::Fg(color::LightGreen), self.task, color::Fg(color::Reset));
                self.apply_index(&repo);

                if self.save_update.is_some() || self.new_task.is_some() {
                    self.save_update(repo, rng);
                    self.reset();
                }
            }
        } else {
            let head = repo.head().unwrap();
            let task = head.shorthand().unwrap();
            if self.task != task {
                println!("  Changing task with no last state, will reset");
                self.reset();
            }
        }
        Ok(new_last_state)
    }

    fn save_update(&mut self, repo: Repository, rng: &mut rand::ThreadRng) {
        let mut yaml = String::new();
        self.convert_to_yaml(&mut yaml);
        let message = format!("{}\n{}", self.message, yaml);

        let mut index = repo.index().unwrap();
        index.read(false).unwrap();
        let author = repo.signature().unwrap();
        let tree_oid = index.write_tree().unwrap();
        let tree = repo.find_tree(tree_oid).unwrap();

        let branch = repo.find_branch(&self.task, BranchType::Local);
        match branch {
            Ok(branch) => {
                let head = branch.into_reference();
                let commit = head.peel(ObjectType::Commit).unwrap();
                repo.commit(Some(&head.name().unwrap()), &author, &author, &message, &tree, &[&commit.as_commit().unwrap()]).unwrap();
            }
            Err(_) => {
                println!("Initial Commit");
                repo.commit(Some("refs/heads/master"), &author, &author, &message, &tree, &[]).unwrap();
            }
        };

        println!("  {}Saved changes to {}{} {:?}", color::Fg(color::LightRed), self.task, color::Fg(color::Reset), self);
        if self.new_task.is_some() {
            let num = rng.gen::<u16>();
            let new_task = format!("{:X}", num);
            println!("  {}Creating task {}{}", color::Fg(color::LightBlue), new_task, color::Fg(color::Reset));
            if let Ok(master_branch) = repo.find_branch("master", BranchType::Local) {
                let master = master_branch.into_reference();
                let commit_obj = master.peel(ObjectType::Commit).unwrap();
                let commit = commit_obj.as_commit().unwrap();
                repo.branch(&new_task, &commit, false).unwrap();
                self.task = new_task;
                self.reset();
            }
        }
    }

    // Constructing the properties YAML from State
    fn convert_to_yaml(&self, mut yaml: &mut String) {
        let mut tasks = Hash::new();
        let mut properties = Hash::new();
        let mut emitter = YamlEmitter::new(&mut yaml);
        for property in self.property.clone() {
            properties.insert(Yaml::String(property.name), Yaml::String(property.value));
        }
        tasks.insert(Yaml::String(self.task.clone()), Yaml::Hash(properties));
        emitter.dump(&Yaml::Hash(tasks)).unwrap();
    }

    fn apply_index(&self, repo: &Repository) {
        let branch = repo.find_branch(&self.task, BranchType::Local);
        let head = match branch {
            Ok(branch) => branch.into_reference(),
            _ => repo.head().unwrap()
        };
        let commit = head.peel(ObjectType::Commit).unwrap();
        let mut index = repo.index().unwrap();

        // apply git index changes only if task is the working directory
        if self.task == repo.head().unwrap().shorthand().unwrap() {
            let to_remove = index.iter().fold(vec![], |mut acc, entry| {
                let entry_path = String::from_utf8_lossy(entry.path.as_ref());
                match self.include.iter().find(|i| i.as_ref() == entry_path) {
                    None => acc.push(entry_path.into_owned()),
                    _ => {}
                };
                acc
            });
            repo.reset_default(Some(&commit), to_remove.iter()).unwrap();
            for change in &self.include {
                let path = Path::new(&change);
                index.add_path(path).unwrap();
            }
            index.write().unwrap();
        }
    }

}
<|endoftext|>


<commit_before>extern crate winapi;
extern crate ws2_32;

use std::io;
use std::os::windows::io::{AsRawSocket, RawSocket};

use self::winapi::{DWORD, LPWSABUF};

use self::ws2_32::{WSASend, WSARecv};

use ::{Rawv, Writev, Readv};

struct WinSock(RawSocket);

impl<T: AsRawSocket> Rawv for T {
    fn readv(&mut self, buffers: &[&mut [u8]]) -> io::Result<usize> {
        WinSock(self.as_raw_socket()).readv(buffers)
    }

    fn writev(&mut self, buffers: &[&[u8]]) -> io::Result<usize> {
        WinSock(self.as_raw_socket()).writev(buffers)
    }
}

impl Writev for WinSock {
    fn writev(&mut self, buffers: &[&[u8]]) -> io::Result<usize> {
        unsafe {
            let mut bytes = 0;
            let ret = WSASend(
                self.0,
                buffers.as_ptr() as LPWSABUF,
                buffers.len() as DWORD,
                &mut bytes,
                0,
                0 as *mut _,
                None
            );
            if ret != 0 {
                Err(io::Error::last_os_error())
            } else {
                Ok(bytes as usize)
            }
        }
    }
}

impl Readv for WinSock {
    fn readv(&mut self, buffers: &[&mut [u8]]) -> io::Result<usize> {
        unsafe {
            let mut bytes = 0;
            let ret = WSARecv(
                self.0,
                buffers.as_ptr() as LPWSABUF,
                buffers.len() as DWORD,
                &mut bytes,
                0 as *mut _,
                0 as *mut _,
                None
            );
            if ret != 0 {
                Err(io::Error::last_os_error())
            } else {
                Ok(ret as usize)
            }
        }
    }
}

#[test]
fn test_rawv() {
    use std::net::{TcpListener, TcpStream};
    use std::thread;

    let acceptor = TcpListener::bind("0.0.0.0:0").unwrap();
    let addr = acceptor.local_addr().unwrap();

    thread::spawn(move || {
        let mut outgoing = TcpStream::connect(addr).unwrap();
        outgoing.writev(&[b"foo", b"bar"]).unwrap();
    });

    let (mut incoming, _) = acceptor.accept().unwrap();
    let mut one = [0u8; 2];
    let mut two = [0u8; 4];

    incoming.readv(&[&mut one, &mut two]).unwrap();
    assert_eq!(&one, b"fo");
    assert_eq!(&two, b"obar");
}
<commit_msg>try different addr for windows test<commit_after>extern crate winapi;
extern crate ws2_32;

use std::io;
use std::os::windows::io::{AsRawSocket, RawSocket};

use self::winapi::{DWORD, LPWSABUF};

use self::ws2_32::{WSASend, WSARecv};

use ::{Rawv, Writev, Readv};

struct WinSock(RawSocket);

impl<T: AsRawSocket> Rawv for T {
    fn readv(&mut self, buffers: &[&mut [u8]]) -> io::Result<usize> {
        WinSock(self.as_raw_socket()).readv(buffers)
    }

    fn writev(&mut self, buffers: &[&[u8]]) -> io::Result<usize> {
        WinSock(self.as_raw_socket()).writev(buffers)
    }
}

impl Writev for WinSock {
    fn writev(&mut self, buffers: &[&[u8]]) -> io::Result<usize> {
        unsafe {
            let mut bytes = 0;
            let ret = WSASend(
                self.0,
                buffers.as_ptr() as LPWSABUF,
                buffers.len() as DWORD,
                &mut bytes,
                0,
                0 as *mut _,
                None
            );
            if ret != 0 {
                Err(io::Error::last_os_error())
            } else {
                Ok(bytes as usize)
            }
        }
    }
}

impl Readv for WinSock {
    fn readv(&mut self, buffers: &[&mut [u8]]) -> io::Result<usize> {
        unsafe {
            let mut bytes = 0;
            let ret = WSARecv(
                self.0,
                buffers.as_ptr() as LPWSABUF,
                buffers.len() as DWORD,
                &mut bytes,
                0 as *mut _,
                0 as *mut _,
                None
            );
            if ret != 0 {
                Err(io::Error::last_os_error())
            } else {
                Ok(ret as usize)
            }
        }
    }
}

#[test]
fn test_rawv() {
    use std::net::{TcpListener, TcpStream};
    use std::thread;

    let acceptor = TcpListener::bind("127.0.0.1:3444").unwrap();
    let addr = acceptor.local_addr().unwrap();

    thread::spawn(move || {
        let mut outgoing = TcpStream::connect(addr).unwrap();
        outgoing.writev(&[b"foo", b"bar"]).unwrap();
    });

    let (mut incoming, _) = acceptor.accept().unwrap();
    let mut one = [0u8; 2];
    let mut two = [0u8; 4];

    incoming.readv(&[&mut one, &mut two]).unwrap();
    assert_eq!(&one, b"fo");
    assert_eq!(&two, b"obar");
}
<|endoftext|>