<commit_before>//! Handles the IPC (Inter-process Communication) protocol used by the renderer client and server.
//!
//! This is the common "language" between client/server. It defines both the protocol for
//! connection and for send messages back and forth.

mod messages;

pub use messages::*;

use std::io;
use std::thread;

use thiserror::Error;
use serde::{Serialize, Deserialize};
use ipc_channel::ipc::{IpcOneShotServer, IpcSender};
use tokio::sync::mpsc;

use crate::renderer_server::RendererServerProcess;

/// The environment variable that is set to indicate that the current process is a server process
pub const RENDERER_PROCESS_ENV_VAR: &str = "RUN_TURTLE_CANVAS";

#[derive(Debug, Error)]
#[error(transparent)]
pub enum ClientConnectionError {
    IpcChannelError(#[from] ipc_channel::Error),
    IOError(#[from] io::Error),
    JoinError(#[from] tokio::task::JoinError),
}

#[derive(Debug, Error)]
#[error(transparent)]
pub enum SendError {
    IpcChannelError(#[from] ipc_channel::Error),
    // IpcError does not implement Display for some reason...
    #[error("IPC Error: {0:?}")]
    IpcError(ipc_channel::ipc::IpcError),
}

impl From<ipc_channel::ipc::IpcError> for SendError {
    fn from(err: ipc_channel::ipc::IpcError) -> Self {
        SendError::IpcError(err)
    }
}

/// Represents either a sender from the connection handshake or a response
#[derive(Debug, Serialize, Deserialize)]
enum HandshakeResponse {
    /// Represents that the handshake has been completed successfully.
    ///
    /// Provides the sender that the client should use to send further requests to the server. This
    /// message is only ever sent **once** for each client at the beginning when the connection is
    /// first established.
    HandshakeFinish(IpcSender<ClientRequest>),

    /// A response from the server sent in response to a request
    Response(ServerResponse),
}

/// Represents one end of an IPC connection
///
/// The connection is parameterized by the type of message that will be sent from this end and
/// received from the other end.
pub struct ClientConnection {
    sender: mpsc::UnboundedSender<ClientRequest>,
    receiver: mpsc::UnboundedReceiver<Result<HandshakeResponse, SendError>>,
}

impl ClientConnection {
    pub async fn new(process: &mut RendererServerProcess) -> Result<Self, ClientConnectionError> {
        // Send the oneshot token to the server which will then respond with its own oneshot token
        let (server, server_name) = tokio::task::spawn_blocking(IpcOneShotServer::new).await??;
        process.writeln(server_name).await?;

        let (server_receiver, response): (_, HandshakeResponse) = tokio::task::spawn_blocking(|| {
            server.accept()
        }).await??;

        let server_sender = match response {
            HandshakeResponse::HandshakeFinish(sender) => sender,
            _ => unreachable!("bug: server did not send back Sender at the end of handshake"),
        };

        // IpcSender and IpcReceiver can't be shared between threads, so we have to spawn our own
        // thread to be able to use them asynchronously.
        let (sender, mut request_receiver) = mpsc::unbounded_channel();
        let (response_sender, receiver) = mpsc::unbounded_channel();
        thread::spawn(move || {
            // This isn't a thread managed by tokio, so it seems like using
            // tokio::task::block_in_place would be inappropriate. Using `block_on` instead, though
            // I'm not sure if this will accidentally spawn a second executor...
            use futures::executor::block_on;

            loop {
                let req = block_on(request_receiver.recv())
                    .expect("bug: the main thread exited earlier than expected");
                // Send the request to the server, then wait for the response
                let response = server_sender.send(req)
                    .map_err(SendError::from)
                    .and_then(|()| server_receiver.recv().map_err(SendError::from));

                response_sender.send(response)
                    .expect("bug: the main thread exited earlier than expected");
            }
        });

        Ok(Self {sender, receiver})
    }

    pub async fn send(&mut self, req: ClientRequest) -> Result<ServerResponse, SendError> {
        self.sender.send(req).expect("bug: the server thread exited earlier than expected");
        let response = self.receiver.recv().await
            .expect("bug: the server thread exited earlier than expected")?;
        match response {
            HandshakeResponse::Response(response) => Ok(response),
            _ => unreachable!("bug: server did not send response after request"),
        }
    }
}
<commit_msg>Fixed client connection documentation<commit_after>//! Handles the IPC (Inter-process Communication) protocol used by the renderer client and server.
//!
//! This is the common "language" between client/server. It defines both the protocol for
//! connection and for send messages back and forth.

mod messages;

pub use messages::*;

use std::io;
use std::thread;

use thiserror::Error;
use serde::{Serialize, Deserialize};
use ipc_channel::ipc::{IpcOneShotServer, IpcSender};
use tokio::sync::mpsc;

use crate::renderer_server::RendererServerProcess;

/// The environment variable that is set to indicate that the current process is a server process
pub const RENDERER_PROCESS_ENV_VAR: &str = "RUN_TURTLE_CANVAS";

#[derive(Debug, Error)]
#[error(transparent)]
pub enum ClientConnectionError {
    IpcChannelError(#[from] ipc_channel::Error),
    IOError(#[from] io::Error),
    JoinError(#[from] tokio::task::JoinError),
}

#[derive(Debug, Error)]
#[error(transparent)]
pub enum SendError {
    IpcChannelError(#[from] ipc_channel::Error),
    // IpcError does not implement Display for some reason...
    #[error("IPC Error: {0:?}")]
    IpcError(ipc_channel::ipc::IpcError),
}

impl From<ipc_channel::ipc::IpcError> for SendError {
    fn from(err: ipc_channel::ipc::IpcError) -> Self {
        SendError::IpcError(err)
    }
}

/// Represents either a sender from the connection handshake or a response
#[derive(Debug, Serialize, Deserialize)]
enum HandshakeResponse {
    /// Represents that the handshake has been completed successfully.
    ///
    /// Provides the sender that the client should use to send further requests to the server. This
    /// message is only ever sent **once** for each client at the beginning when the connection is
    /// first established.
    HandshakeFinish(IpcSender<ClientRequest>),

    /// A response from the server sent in response to a request
    Response(ServerResponse),
}

/// Represents the client side of the IPC connection
pub struct ClientConnection {
    sender: mpsc::UnboundedSender<ClientRequest>,
    receiver: mpsc::UnboundedReceiver<Result<HandshakeResponse, SendError>>,
}

impl ClientConnection {
    pub async fn new(process: &mut RendererServerProcess) -> Result<Self, ClientConnectionError> {
        // Send the oneshot token to the server which will then respond with its own oneshot token
        let (server, server_name) = tokio::task::spawn_blocking(IpcOneShotServer::new).await??;
        process.writeln(server_name).await?;

        let (server_receiver, response): (_, HandshakeResponse) = tokio::task::spawn_blocking(|| {
            server.accept()
        }).await??;

        let server_sender = match response {
            HandshakeResponse::HandshakeFinish(sender) => sender,
            _ => unreachable!("bug: server did not send back Sender at the end of handshake"),
        };

        // IpcSender and IpcReceiver can't be shared between threads, so we have to spawn our own
        // thread to be able to use them asynchronously.
        let (sender, mut request_receiver) = mpsc::unbounded_channel();
        let (response_sender, receiver) = mpsc::unbounded_channel();
        thread::spawn(move || {
            // This isn't a thread managed by tokio, so it seems like using
            // tokio::task::block_in_place would be inappropriate. Using `block_on` instead, though
            // I'm not sure if this will accidentally spawn a second executor...
            use futures::executor::block_on;

            loop {
                let req = block_on(request_receiver.recv())
                    .expect("bug: the main thread exited earlier than expected");
                // Send the request to the server, then wait for the response
                let response = server_sender.send(req)
                    .map_err(SendError::from)
                    .and_then(|()| server_receiver.recv().map_err(SendError::from));

                response_sender.send(response)
                    .expect("bug: the main thread exited earlier than expected");
            }
        });

        Ok(Self {sender, receiver})
    }

    pub async fn send(&mut self, req: ClientRequest) -> Result<ServerResponse, SendError> {
        self.sender.send(req).expect("bug: the server thread exited earlier than expected");
        let response = self.receiver.recv().await
            .expect("bug: the server thread exited earlier than expected")?;
        match response {
            HandshakeResponse::Response(response) => Ok(response),
            _ => unreachable!("bug: server did not send response after request"),
        }
    }
}
<|endoftext|>


<commit_before>use nom::{alphanumeric, digit, multispace};
use std::collections::{HashSet, VecDeque};
use std::str;

use column::Column;
use common::{binary_comparison_operator, binary_logical_operator, column_identifier,
             unary_negation_operator, Operator};

#[derive(Clone, Debug, PartialEq)]
pub enum ConditionBase {
    Field(Column),
    Literal(String),
    Placeholder,
}

#[derive(Clone, Debug, PartialEq)]
pub struct ConditionTree {
    pub operator: Operator,
    pub left: Option<Box<ConditionExpression>>,
    pub right: Option<Box<ConditionExpression>>,
}

impl<'a> ConditionTree {
    fn contained_columns(&'a self) -> HashSet<&'a Column> {
        let mut s = HashSet::new();
        let mut q = VecDeque::<&'a ConditionTree>::new();
        q.push_back(self);
        while let Some(ref ct) = q.pop_front() {
            match **ct.left.as_ref().unwrap() {
                ConditionExpression::Base(ConditionBase::Field(ref c)) => {
                    s.insert(c);
                }
                ConditionExpression::LogicalOp(ref ct) |
                ConditionExpression::ComparisonOp(ref ct) => q.push_back(ct),
                _ => (),
            }
            match **ct.right.as_ref().unwrap() {
                ConditionExpression::Base(ConditionBase::Field(ref c)) => {
                    s.insert(c);
                }
                ConditionExpression::LogicalOp(ref ct) |
                ConditionExpression::ComparisonOp(ref ct) => q.push_back(ct),
                _ => (),
            }
        }
        s
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum ConditionExpression {
    ComparisonOp(ConditionTree),
    LogicalOp(ConditionTree),
    Base(ConditionBase),
}

fn fold_cond_exprs(initial: ConditionExpression,
                   remainder: Vec<(Operator, ConditionExpression)>)
                   -> ConditionExpression {
    remainder.into_iter().fold(initial, |acc, pair| {
        let (oper, expr) = pair;
        match oper {
            Operator::Equal | Operator::Less | Operator::Greater | Operator::LessOrEqual |
            Operator::Like | Operator::GreaterOrEqual | Operator::NotEqual => {
                ConditionExpression::ComparisonOp(ConditionTree {
                    operator: oper.clone(),
                    left: Some(Box::new(acc)),
                    right: Some(Box::new(expr)),
                })
            }
            Operator::And | Operator::Or => {
                ConditionExpression::LogicalOp(ConditionTree {
                    operator: oper.clone(),
                    left: Some(Box::new(acc)),
                    right: Some(Box::new(expr)),
                })
            }
            o => {
                println!("unsupported op {:?}", o);
                unimplemented!()
            }
        }
    })
}

/// Parse a conditional expression into a condition tree structure
named!(pub condition_expr<&[u8], ConditionExpression>,
    chain!(
        neg_op: opt!(unary_negation_operator) ~
        initial: boolean_primary ~
        remainder: many0!(
            complete!(
                chain!(
                    log_op: delimited!(opt!(multispace),
                                       binary_logical_operator,
                                       opt!(multispace)) ~
                    right_expr: condition_expr,
                    || {
                        (log_op, right_expr)
                    }
                )
            )
        ),
        || {
            if let Some(Operator::Not) = neg_op {
                ConditionExpression::LogicalOp(
                    ConditionTree {
                        operator: Operator::Not,
                        left: Some(Box::new(fold_cond_exprs(initial, remainder))),
                        right: None,
                    }
                )
            } else {
                fold_cond_exprs(initial, remainder)
            }
        }
    )
);

named!(boolean_primary<&[u8], ConditionExpression>,
    chain!(
        initial: predicate ~
        remainder:
        many0!(
            complete!(
                chain!(
                    op: delimited!(opt!(multispace),
                                   binary_comparison_operator,
                                   opt!(multispace)) ~
                    right_expr: boolean_primary,
                    || {
                        (op, right_expr)
                    }
                )
            )
        ),
        || { fold_cond_exprs(initial, remainder) }
    )
);

named!(predicate<&[u8], ConditionExpression>,
    alt_complete!(
            chain!(
                delimited!(opt!(multispace), tag!("?"), opt!(multispace)),
                || {
                    ConditionExpression::Base(
                        ConditionBase::Placeholder
                    )
                }
            )
        |   chain!(
                field: delimited!(opt!(multispace), digit, opt!(multispace)),
                || {
                    ConditionExpression::Base(
                        ConditionBase::Literal(String::from(str::from_utf8(field).unwrap()))
                    )
                }
            )
        |   chain!(
                field: delimited!(opt!(multispace),
                                  alt_complete!(
                                        delimited!(tag!("\""), alphanumeric, tag!("\""))
                                      | delimited!(tag!("'"), alphanumeric, tag!("'"))
                                  ),
                                  opt!(multispace)),
                || {
                    ConditionExpression::Base(
                        ConditionBase::Literal(String::from(str::from_utf8(field).unwrap()))
                    )
                }
            )
        |   chain!(
                field: delimited!(opt!(multispace), column_identifier, opt!(multispace)),
                || {
                    ConditionExpression::Base(
                        ConditionBase::Field(field)
                    )
                }
            )
    )
);

#[cfg(test)]
mod tests {
    use super::*;
    use column::Column;
    use common::Operator;

    fn flat_condition_tree(op: Operator,
                           l: ConditionBase,
                           r: ConditionBase)
                           -> ConditionExpression {
        ConditionExpression::ComparisonOp(ConditionTree {
            operator: op,
            left: Some(Box::new(ConditionExpression::Base(l))),
            right: Some(Box::new(ConditionExpression::Base(r))),
        })
    }

    #[test]
    fn ct_contained_columns() {
        use std::collections::HashSet;

        let cond = "a.foo = ? and b.bar = 42";

        let res = condition_expr(cond.as_bytes());
        let c1 = Column::from("a.foo");
        let c2 = Column::from("b.bar");
        let mut expected_cols = HashSet::new();
        expected_cols.insert(&c1);
        expected_cols.insert(&c2);
        match res.unwrap().1 {
            ConditionExpression::LogicalOp(ct) => {
                assert_eq!(ct.contained_columns(), expected_cols);
            }
            _ => panic!(),
        }
    }

    #[test]
    fn equality_placeholder() {
        let cond = "foo = ?";

        let res = condition_expr(cond.as_bytes());
        assert_eq!(res.unwrap().1,
                   flat_condition_tree(Operator::Equal,
                                       ConditionBase::Field(Column::from("foo")),
                                       ConditionBase::Placeholder)
                  );
    }

    #[test]
    fn equality_literals() {
        let cond1 = "foo = 42";
        let cond2 = "foo = \"hello\"";

        let res1 = condition_expr(cond1.as_bytes());
        assert_eq!(res1.unwrap().1,
                   flat_condition_tree(Operator::Equal,
                                       ConditionBase::Field(Column::from("foo")),
                                       ConditionBase::Literal(String::from("42"))
                                      )
                   );

        let res2 = condition_expr(cond2.as_bytes());
        assert_eq!(res2.unwrap().1,
                   flat_condition_tree(Operator::Equal,
                                       ConditionBase::Field(Column::from("foo")),
                                       ConditionBase::Literal(String::from("hello"))
                                      )
                   );
    }

    #[test]
    fn inequality_literals() {
        let cond1 = "foo >= 42";
        let cond2 = "foo <= 5";

        let res1 = condition_expr(cond1.as_bytes());
        assert_eq!(res1.unwrap().1,
                   flat_condition_tree(Operator::GreaterOrEqual,
                                       ConditionBase::Field(Column::from("foo")),
                                       ConditionBase::Literal(String::from("42"))
                                      )
                   );

        let res2 = condition_expr(cond2.as_bytes());
        assert_eq!(res2.unwrap().1,
                   flat_condition_tree(Operator::LessOrEqual,
                                       ConditionBase::Field(Column::from("foo")),
                                       ConditionBase::Literal(String::from("5"))
                                      )
                   );
    }
}
<commit_msg>Make `contained_columns` method public<commit_after>use nom::{alphanumeric, digit, multispace};
use std::collections::{HashSet, VecDeque};
use std::str;

use column::Column;
use common::{binary_comparison_operator, binary_logical_operator, column_identifier,
             unary_negation_operator, Operator};

#[derive(Clone, Debug, PartialEq)]
pub enum ConditionBase {
    Field(Column),
    Literal(String),
    Placeholder,
}

#[derive(Clone, Debug, PartialEq)]
pub struct ConditionTree {
    pub operator: Operator,
    pub left: Option<Box<ConditionExpression>>,
    pub right: Option<Box<ConditionExpression>>,
}

impl<'a> ConditionTree {
    pub fn contained_columns(&'a self) -> HashSet<&'a Column> {
        let mut s = HashSet::new();
        let mut q = VecDeque::<&'a ConditionTree>::new();
        q.push_back(self);
        while let Some(ref ct) = q.pop_front() {
            match **ct.left.as_ref().unwrap() {
                ConditionExpression::Base(ConditionBase::Field(ref c)) => {
                    s.insert(c);
                }
                ConditionExpression::LogicalOp(ref ct) |
                ConditionExpression::ComparisonOp(ref ct) => q.push_back(ct),
                _ => (),
            }
            match **ct.right.as_ref().unwrap() {
                ConditionExpression::Base(ConditionBase::Field(ref c)) => {
                    s.insert(c);
                }
                ConditionExpression::LogicalOp(ref ct) |
                ConditionExpression::ComparisonOp(ref ct) => q.push_back(ct),
                _ => (),
            }
        }
        s
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum ConditionExpression {
    ComparisonOp(ConditionTree),
    LogicalOp(ConditionTree),
    Base(ConditionBase),
}

fn fold_cond_exprs(initial: ConditionExpression,
                   remainder: Vec<(Operator, ConditionExpression)>)
                   -> ConditionExpression {
    remainder.into_iter().fold(initial, |acc, pair| {
        let (oper, expr) = pair;
        match oper {
            Operator::Equal | Operator::Less | Operator::Greater | Operator::LessOrEqual |
            Operator::Like | Operator::GreaterOrEqual | Operator::NotEqual => {
                ConditionExpression::ComparisonOp(ConditionTree {
                    operator: oper.clone(),
                    left: Some(Box::new(acc)),
                    right: Some(Box::new(expr)),
                })
            }
            Operator::And | Operator::Or => {
                ConditionExpression::LogicalOp(ConditionTree {
                    operator: oper.clone(),
                    left: Some(Box::new(acc)),
                    right: Some(Box::new(expr)),
                })
            }
            o => {
                println!("unsupported op {:?}", o);
                unimplemented!()
            }
        }
    })
}

/// Parse a conditional expression into a condition tree structure
named!(pub condition_expr<&[u8], ConditionExpression>,
    chain!(
        neg_op: opt!(unary_negation_operator) ~
        initial: boolean_primary ~
        remainder: many0!(
            complete!(
                chain!(
                    log_op: delimited!(opt!(multispace),
                                       binary_logical_operator,
                                       opt!(multispace)) ~
                    right_expr: condition_expr,
                    || {
                        (log_op, right_expr)
                    }
                )
            )
        ),
        || {
            if let Some(Operator::Not) = neg_op {
                ConditionExpression::LogicalOp(
                    ConditionTree {
                        operator: Operator::Not,
                        left: Some(Box::new(fold_cond_exprs(initial, remainder))),
                        right: None,
                    }
                )
            } else {
                fold_cond_exprs(initial, remainder)
            }
        }
    )
);

named!(boolean_primary<&[u8], ConditionExpression>,
    chain!(
        initial: predicate ~
        remainder:
        many0!(
            complete!(
                chain!(
                    op: delimited!(opt!(multispace),
                                   binary_comparison_operator,
                                   opt!(multispace)) ~
                    right_expr: boolean_primary,
                    || {
                        (op, right_expr)
                    }
                )
            )
        ),
        || { fold_cond_exprs(initial, remainder) }
    )
);

named!(predicate<&[u8], ConditionExpression>,
    alt_complete!(
            chain!(
                delimited!(opt!(multispace), tag!("?"), opt!(multispace)),
                || {
                    ConditionExpression::Base(
                        ConditionBase::Placeholder
                    )
                }
            )
        |   chain!(
                field: delimited!(opt!(multispace), digit, opt!(multispace)),
                || {
                    ConditionExpression::Base(
                        ConditionBase::Literal(String::from(str::from_utf8(field).unwrap()))
                    )
                }
            )
        |   chain!(
                field: delimited!(opt!(multispace),
                                  alt_complete!(
                                        delimited!(tag!("\""), alphanumeric, tag!("\""))
                                      | delimited!(tag!("'"), alphanumeric, tag!("'"))
                                  ),
                                  opt!(multispace)),
                || {
                    ConditionExpression::Base(
                        ConditionBase::Literal(String::from(str::from_utf8(field).unwrap()))
                    )
                }
            )
        |   chain!(
                field: delimited!(opt!(multispace), column_identifier, opt!(multispace)),
                || {
                    ConditionExpression::Base(
                        ConditionBase::Field(field)
                    )
                }
            )
    )
);

#[cfg(test)]
mod tests {
    use super::*;
    use column::Column;
    use common::Operator;

    fn flat_condition_tree(op: Operator,
                           l: ConditionBase,
                           r: ConditionBase)
                           -> ConditionExpression {
        ConditionExpression::ComparisonOp(ConditionTree {
            operator: op,
            left: Some(Box::new(ConditionExpression::Base(l))),
            right: Some(Box::new(ConditionExpression::Base(r))),
        })
    }

    #[test]
    fn ct_contained_columns() {
        use std::collections::HashSet;

        let cond = "a.foo = ? and b.bar = 42";

        let res = condition_expr(cond.as_bytes());
        let c1 = Column::from("a.foo");
        let c2 = Column::from("b.bar");
        let mut expected_cols = HashSet::new();
        expected_cols.insert(&c1);
        expected_cols.insert(&c2);
        match res.unwrap().1 {
            ConditionExpression::LogicalOp(ct) => {
                assert_eq!(ct.contained_columns(), expected_cols);
            }
            _ => panic!(),
        }
    }

    #[test]
    fn equality_placeholder() {
        let cond = "foo = ?";

        let res = condition_expr(cond.as_bytes());
        assert_eq!(res.unwrap().1,
                   flat_condition_tree(Operator::Equal,
                                       ConditionBase::Field(Column::from("foo")),
                                       ConditionBase::Placeholder)
                  );
    }

    #[test]
    fn equality_literals() {
        let cond1 = "foo = 42";
        let cond2 = "foo = \"hello\"";

        let res1 = condition_expr(cond1.as_bytes());
        assert_eq!(res1.unwrap().1,
                   flat_condition_tree(Operator::Equal,
                                       ConditionBase::Field(Column::from("foo")),
                                       ConditionBase::Literal(String::from("42"))
                                      )
                   );

        let res2 = condition_expr(cond2.as_bytes());
        assert_eq!(res2.unwrap().1,
                   flat_condition_tree(Operator::Equal,
                                       ConditionBase::Field(Column::from("foo")),
                                       ConditionBase::Literal(String::from("hello"))
                                      )
                   );
    }

    #[test]
    fn inequality_literals() {
        let cond1 = "foo >= 42";
        let cond2 = "foo <= 5";

        let res1 = condition_expr(cond1.as_bytes());
        assert_eq!(res1.unwrap().1,
                   flat_condition_tree(Operator::GreaterOrEqual,
                                       ConditionBase::Field(Column::from("foo")),
                                       ConditionBase::Literal(String::from("42"))
                                      )
                   );

        let res2 = condition_expr(cond2.as_bytes());
        assert_eq!(res2.unwrap().1,
                   flat_condition_tree(Operator::LessOrEqual,
                                       ConditionBase::Field(Column::from("foo")),
                                       ConditionBase::Literal(String::from("5"))
                                      )
                   );
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use num::FromPrimitive;

#[derive(Debug)]
pub struct FuncConst {
    pub arg_count: u32,
    pub local_count: u32,
    pub body: Vec<u8>
}

#[derive(Default)]
pub struct ConstTable {
    pub funcs: Vec<FuncConst>,
    pub bc_counter: usize
}

impl fmt::Debug for ConstTable {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        //TODO
        unimplemented!()
    }
}

pub fn read_const_table(data: &[u8]) -> ConstTable {

    let mut const_table: ConstTable = Default::default();

    macro_rules! get_next_4_bytes {
        () => {{
            let val = (data[const_table.bc_counter] as u32) << 24 |
            (data[const_table.bc_counter + 1] as u32) << 16 |
            (data[const_table.bc_counter + 2] as u32) << 8 |
            (data[const_table.bc_counter + 3] as u32);
            const_table.bc_counter += 4;
            debug!("get_next_4_bytes: 0x{:04X}", val);
            val
        }}
    }

    while const_table.bc_counter != data.len() {

        let instr = ConstInstr::from_u8(data[const_table.bc_counter]);

        const_table.bc_counter += 1;
        if instr.is_none() {
            warn!("Unimplemented constants table instruction: {:04X}", data[const_table.bc_counter - 1]);
            continue;
        }

        let instr = instr.unwrap();

        match instr {
            ConstInstr::FUNC => {
                // TODO: remove this on the compiler end
                get_next_4_bytes!();
                // TODO: Im so sorry, this is terrible
                const_table.funcs.push(FuncConst {
                    arg_count: get_next_4_bytes!(),
                    local_count: get_next_4_bytes!(),
                    body: data[const_table.bc_counter..{const_table.bc_counter += get_next_4_bytes!() as usize; const_table.bc_counter}].to_vec()
                });
                debug!("Added a function to the constants table");
            },
            ConstInstr::END => {
                debug!("Reached end of constants table");
                break;
            }
        }
    }
    const_table
}

enum_from_primitive! {
    #[allow(non_camel_case_types)]
    #[derive(Debug, PartialEq)]
    pub enum ConstInstr {
        FUNC = 0xF0,
        END = 0xED
    }
}
<commit_msg>Fix constants table<commit_after>use std::fmt;
use num::FromPrimitive;

#[derive(Debug)]
pub struct FuncConst {
    pub arg_count: u32,
    pub local_count: u32,
    pub body: Vec<u8>
}

#[derive(Default)]
pub struct ConstTable {
    pub funcs: Vec<FuncConst>,
    pub bc_counter: usize
}

impl fmt::Debug for ConstTable {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        //TODO
        unimplemented!()
    }
}

pub fn read_const_table(data: &[u8]) -> ConstTable {

    let mut const_table: ConstTable = Default::default();

    macro_rules! get_next_4_bytes {
        () => {{
            let val = (data[const_table.bc_counter] as u32) << 24 |
            (data[const_table.bc_counter + 1] as u32) << 16 |
            (data[const_table.bc_counter + 2] as u32) << 8 |
            (data[const_table.bc_counter + 3] as u32);
            const_table.bc_counter += 4;
            debug!("get_next_4_bytes: 0x{:04X}", val);
            val
        }}
    }

    while const_table.bc_counter != data.len() {

        let instr = ConstInstr::from_u8(data[const_table.bc_counter]);

        const_table.bc_counter += 1;
        if instr.is_none() {
            warn!("Unimplemented constants table instruction: {:04X}", data[const_table.bc_counter - 1]);
            continue;
        }

        let instr = instr.unwrap();

        match instr {
            ConstInstr::FUNC => {
                // TODO: remove this on the compiler end
                get_next_4_bytes!();
                // TODO: Im so sorry, this is terrible
                const_table.funcs.push(FuncConst {
                    arg_count: get_next_4_bytes!(),
                    local_count: get_next_4_bytes!(),
                    body: data[const_table.bc_counter..{const_table.bc_counter += (4 + get_next_4_bytes!()) as usize; const_table.bc_counter + 1}].to_vec()
                });
                debug!("Added a function to the constants table");
            },
            ConstInstr::END => {
                debug!("Reached end of constants table");
                break;
            }
        }
    }
    const_table
}

enum_from_primitive! {
    #[allow(non_camel_case_types)]
    #[derive(Debug, PartialEq)]
    pub enum ConstInstr {
        FUNC = 0xF0,
        END = 0xED
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use num::FromPrimitive;

#[derive(Debug)]
pub struct FuncConst {
    arg_count: u32,
    local_count: u32,
    body: Vec<u8>
}

#[derive(Default)]
pub struct ConstTable {
    funcs: Vec<FuncConst>
    // TODO: Add more types
}

impl fmt::Debug for ConstTable {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        //TODO
        unimplemented!()
    }
}

pub fn read_const_table(mut data: &[u8]) -> ConstTable {

    let mut bc_counter = 0;
    let mut const_table: ConstTable = Default::default();

    macro_rules! get_next_4_bytes {
        () => {{
            let val = (data[bc_counter] as u32) << 24 |
            (data[bc_counter + 1] as u32) << 16 |
            (data[bc_counter + 2] as u32) << 8 |
            (data[bc_counter + 3] as u32);
            bc_counter += 4;
            debug!("get_next_4_bytes: 0x{:04X}", val);
            val
        }}
    }

    while bc_counter != data.len() {

        let instr = ConstInstr::from_u8(data[bc_counter]);
        bc_counter += 1;

        if instr.is_none() {
            warn!("Unimplemented constants table instruction: {:04X}", data[bc_counter]);
            continue;
        }

        let instr = instr.unwrap();

        match instr {
            ConstInstr::FUNC => {
                let id = get_next_4_bytes!(); let arg_count = get_next_4_bytes!(); let local_count = get_next_4_bytes!();
                let length = get_next_4_bytes!();
                const_table.funcs[id] = FuncConst {
                    arg_count: arg_count,
                    local_count: local_count,
                    body: data[bc_counter..(bc_counter+length as usize)]
                }
            },
            ConstInstr::END => {}
        }
    }
    const_table
}

enum_from_primitive! {
    #[allow(non_camel_case_types)]
    #[derive(Debug, PartialEq)]
    pub enum ConstInstr {
        FUNC = 0xF0,
        END = 0xED
    }
}
<commit_msg>Small changes, functions still incomplete<commit_after>use std::fmt;
use num::FromPrimitive;

#[derive(Debug)]
pub struct FuncConst {
    arg_count: u32,
    local_count: u32,
    body: Vec<u8>
}

#[derive(Default)]
pub struct ConstTable {
    funcs: Vec<FuncConst>
    // TODO: Add more types
}

impl fmt::Debug for ConstTable {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        //TODO
        unimplemented!()
    }
}

pub fn read_const_table(data: &[u8]) -> ConstTable {

    let mut bc_counter = 0;
    let mut const_table: ConstTable = Default::default();

    macro_rules! get_next_4_bytes {
        () => {{
            let val = (data[bc_counter] as u32) << 24 |
            (data[bc_counter + 1] as u32) << 16 |
            (data[bc_counter + 2] as u32) << 8 |
            (data[bc_counter + 3] as u32);
            bc_counter += 4;
            debug!("get_next_4_bytes: 0x{:04X}", val);
            val
        }}
    }

    while bc_counter != data.len() {

        let instr = ConstInstr::from_u8(data[bc_counter]);
        bc_counter += 1;

        if instr.is_none() {
            warn!("Unimplemented constants table instruction: {:04X}", data[bc_counter]);
            continue;
        }

        let instr = instr.unwrap();

        match instr {
            ConstInstr::FUNC => {
                const_table.funcs[get_next_4_bytes!() as usize] = FuncConst {
                    arg_count: get_next_4_bytes!(),
                    local_count: get_next_4_bytes!(),
                    body: data[bc_counter..(bc_counter+get_next_4_bytes!() as usize)].to_vec()
                };
                debug!("Added a function to the constants table")
            },
            ConstInstr::END => {
                debug!("Reached end of constants table");
                break;
            }
        }
    }
    const_table
}

enum_from_primitive! {
    #[allow(non_camel_case_types)]
    #[derive(Debug, PartialEq)]
    pub enum ConstInstr {
        FUNC = 0xF0,
        END = 0xED
    }
}
<|endoftext|>


<commit_before>use crate::{Lang, Script};

const RELIABLE_CONFIDENCE_THRESHOLD: f64 = 0.9;

/// Represents a full outcome of language detection.
#[derive(Debug, PartialEq)]
pub struct Info {
    script: Script,
    lang: Lang,
    confidence: f64,
}

impl Info {
    pub fn new(script: Script, lang: Lang, confidence: f64) -> Self {
        Self {
            script,
            lang,
            confidence,
        }
    }

    pub fn lang(&self) -> Lang {
        self.lang
    }

    pub fn script(&self) -> Script {
        self.script
    }

    pub fn confidence(&self) -> f64 {
        self.confidence
    }

    pub fn is_reliable(&self) -> bool {
        self.confidence > RELIABLE_CONFIDENCE_THRESHOLD
    }
}
<commit_msg>Kill one more mutant<commit_after>use crate::{Lang, Script};

const RELIABLE_CONFIDENCE_THRESHOLD: f64 = 0.9;

/// Represents a full outcome of language detection.
#[derive(Debug, PartialEq)]
pub struct Info {
    script: Script,
    lang: Lang,
    confidence: f64,
}

impl Info {
    pub fn new(script: Script, lang: Lang, confidence: f64) -> Self {
        Self {
            script,
            lang,
            confidence,
        }
    }

    pub fn lang(&self) -> Lang {
        self.lang
    }

    pub fn script(&self) -> Script {
        self.script
    }

    pub fn confidence(&self) -> f64 {
        self.confidence
    }

    pub fn is_reliable(&self) -> bool {
        self.confidence > RELIABLE_CONFIDENCE_THRESHOLD
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_is_realiable() {
        let mut info = Info {
            script: Script::Greek,
            lang: Lang::Ell,
            confidence: 0.0,
        };
        assert_eq!(info.is_reliable(), false);

        info.confidence = 1.0;
        assert_eq!(info.is_reliable(), true);
    }
}
<|endoftext|>


<commit_before>#[cfg(test)]
use rand::Rand;

use rand::Rng;

#[inline]
fn sbx_beta(u: f32, eta: f32) -> f32 {
    debug_assert!(u >= 0.0 && u < 1.0);

    if u <= 0.5 {
        2.0 * u
    } else {
        1.0 / (2.0 * (1.0 - u))
    }
    .powf(1.0 / (eta + 1.0))
}

#[inline]
fn sbx_beta_bounded(u: f32, eta: f32, gamma: f32) -> f32 {
    debug_assert!(u >= 0.0 && u < 1.0);

    let g = 1.0 - gamma;
    let ug = u * g;

    if u <= 0.5 / g {
        2.0 * ug
    } else {
        1.0 / (2.0 * (1.0 - ug))
    }
    .powf(1.0 / (eta + 1.0))
}

#[inline]
pub fn sbx_single_var<R: Rng>(rng: &mut R, p: (f32, f32), eta: f32) -> (f32, f32) {
    let u = rng.gen::<f32>();
    let beta = sbx_beta(u, eta);

    (0.5 * (((1.0 + beta) * p.0) + ((1.0 - beta) * p.1)),
     0.5 * (((1.0 - beta) * p.0) + ((1.0 + beta) * p.1)))
}

#[inline]
fn _sbx_single_var_bounded<R: Rng>(rng: &mut R,
                                   p: (f32, f32),
                                   bounds: (f32, f32),
                                   eta: f32)
                                   -> (f32, f32) {
    let (a, b) = bounds;
    let p_diff = p.1 - p.0;

    assert!(a <= b);
    assert!(p_diff > 0.0);

    let beta_a = 1.0 + (p.0 - a) / p_diff;
    let beta_b = 1.0 + (b - p.1) / p_diff;

    fn gamma(beta: f32, eta: f32) -> f32 {
        1.0 / (2.0 * beta.powf(eta + 1.0))
    }

    let gamma_a = gamma(beta_a, eta);
    let gamma_b = gamma(beta_b, eta);

    let u = rng.gen::<f32>();
    let beta_ua = sbx_beta_bounded(u, eta, gamma_a);
    let beta_ub = sbx_beta_bounded(u, eta, gamma_b);

    (0.5 * (((1.0 + beta_ua) * p.0) + ((1.0 - beta_ua) * p.1)),
     0.5 * (((1.0 - beta_ub) * p.0) + ((1.0 + beta_ub) * p.1)))
}

#[inline]
pub fn sbx_single_var_bounded<R: Rng>(rng: &mut R,
                                      p: (f32, f32),
                                      bounds: (f32, f32),
                                      eta: f32)
                                      -> (f32, f32) {
    if p.0 < p.1 {
        _sbx_single_var_bounded(rng, (p.0, p.1), bounds, eta)
    } else if p.0 > p.1 {
        let r = _sbx_single_var_bounded(rng, (p.1, p.0), bounds, eta);
        (r.1, r.0)
    } else {
        debug_assert!(p.0 == p.1);
        (p.0, p.1)
    }
}

/// Modifies ind1 and ind2 in-place.
/// Reference: http://www.iitk.ac.in/kangal/papers/k2011017.pdf
pub fn simulated_binary_crossover<R: Rng>(rng: &mut R,
                                          ind1: &mut [f32],
                                          ind2: &mut [f32],
                                          eta: f32) {
    assert!(ind1.len() == ind2.len());

    let mut iter = ind1.iter_mut().zip(ind2.iter_mut());
    for (x1, x2) in iter {
        let (c1, c2) = sbx_single_var(rng, (*x1, *x2), eta);
        *x1 = c1;
        *x2 = c2;
    }
}

#[test]
fn test_sbx() {
    let mut rng = ::rand::isaac::Isaac64Rng::new_unseeded();

    let parent1 = vec![1.0, 2.0];
    let parent2 = vec![100.0, 1.0];

    let mut child1 = parent1.clone();
    let mut child2 = parent2.clone();

    simulated_binary_crossover(&mut rng, &mut child1[..], &mut child2[..], 2.0);

    let beta: Vec<_> = (0..2)
                           .map(|i| (child2[i] - child1[i]) / (parent2[i] - parent1[i]))
                           .collect();

    println!("({:?}, {:?}) => ({:?}, {:?})",
             parent1,
             parent2,
             child1,
             child2);
    println!("beta: {:?}", beta);
}
<commit_msg>Add some assertions<commit_after>#[cfg(test)]
use rand::Rand;

use rand::Rng;

#[inline]
fn sbx_beta(u: f32, eta: f32) -> f32 {
    assert!(u >= 0.0 && u < 1.0);

    if u <= 0.5 {
        2.0 * u
    } else {
        1.0 / (2.0 * (1.0 - u))
    }
    .powf(1.0 / (eta + 1.0))
}

#[inline]
fn sbx_beta_bounded(u: f32, eta: f32, gamma: f32) -> f32 {
    assert!(u >= 0.0 && u < 1.0);

    let g = 1.0 - gamma;
    let ug = u * g;

    if u <= 0.5 / g {
        2.0 * ug
    } else {
        1.0 / (2.0 * (1.0 - ug))
    }
    .powf(1.0 / (eta + 1.0))
}

#[inline]
pub fn sbx_single_var<R: Rng>(rng: &mut R, p: (f32, f32), eta: f32) -> (f32, f32) {
    let u = rng.gen::<f32>();
    let beta = sbx_beta(u, eta);

    (0.5 * (((1.0 + beta) * p.0) + ((1.0 - beta) * p.1)),
     0.5 * (((1.0 - beta) * p.0) + ((1.0 + beta) * p.1)))
}

#[inline]
fn _sbx_single_var_bounded<R: Rng>(rng: &mut R,
                                   p: (f32, f32),
                                   bounds: (f32, f32),
                                   eta: f32)
                                   -> (f32, f32) {
    let (a, b) = bounds;
    let p_diff = p.1 - p.0;

    assert!(a <= b);
    assert!(p_diff > 0.0);
    assert!(p.0 >= a && p.0 <= b);
    assert!(p.1 >= a && p.1 <= b);

    let beta_a = 1.0 + (p.0 - a) / p_diff;
    let beta_b = 1.0 + (b - p.1) / p_diff;

    fn gamma(beta: f32, eta: f32) -> f32 {
        1.0 / (2.0 * beta.powf(eta + 1.0))
    }

    let gamma_a = gamma(beta_a, eta);
    let gamma_b = gamma(beta_b, eta);

    let u = rng.gen::<f32>();
    let beta_ua = sbx_beta_bounded(u, eta, gamma_a);
    let beta_ub = sbx_beta_bounded(u, eta, gamma_b);

    let c = (0.5 * (((1.0 + beta_ua) * p.0) + ((1.0 - beta_ua) * p.1)),
             0.5 * (((1.0 - beta_ub) * p.0) + ((1.0 + beta_ub) * p.1)));

    assert!(c.0 >= a && c.0 <= b);
    assert!(c.1 >= a && c.1 <= b);

    return c;
}

#[inline]
pub fn sbx_single_var_bounded<R: Rng>(rng: &mut R,
                                      p: (f32, f32),
                                      bounds: (f32, f32),
                                      eta: f32)
                                      -> (f32, f32) {
    if p.0 < p.1 {
        _sbx_single_var_bounded(rng, (p.0, p.1), bounds, eta)
    } else if p.0 > p.1 {
        let r = _sbx_single_var_bounded(rng, (p.1, p.0), bounds, eta);
        (r.1, r.0)
    } else {
        debug_assert!(p.0 == p.1);
        (p.0, p.1)
    }
}

/// Modifies ind1 and ind2 in-place.
/// Reference: http://www.iitk.ac.in/kangal/papers/k2011017.pdf
pub fn simulated_binary_crossover<R: Rng>(rng: &mut R,
                                          ind1: &mut [f32],
                                          ind2: &mut [f32],
                                          eta: f32) {
    assert!(ind1.len() == ind2.len());

    let mut iter = ind1.iter_mut().zip(ind2.iter_mut());
    for (x1, x2) in iter {
        let (c1, c2) = sbx_single_var(rng, (*x1, *x2), eta);
        *x1 = c1;
        *x2 = c2;
    }
}

#[test]
fn test_sbx() {
    let mut rng = ::rand::isaac::Isaac64Rng::new_unseeded();

    let parent1 = vec![1.0, 2.0];
    let parent2 = vec![100.0, 1.0];

    let mut child1 = parent1.clone();
    let mut child2 = parent2.clone();

    simulated_binary_crossover(&mut rng, &mut child1[..], &mut child2[..], 2.0);

    let beta: Vec<_> = (0..2)
                           .map(|i| (child2[i] - child1[i]) / (parent2[i] - parent1[i]))
                           .collect();

    println!("({:?}, {:?}) => ({:?}, {:?})",
             parent1,
             parent2,
             child1,
             child2);
    println!("beta: {:?}", beta);
}
<|endoftext|>


<commit_before>//! Abstractions for asynchronous programming.
//!
//! This crate provides a number of core abstractions for writing asynchronous
//! code:
//!
//! - [Futures](crate::future::Future) are single eventual values produced by
//!   asychronous computations. Some programming languages (e.g. JavaScript)
//!   call this concept "promise".
//! - [Streams](crate::stream::Stream) represent a series of values
//!   produced asynchronously.
//! - [Sinks](crate::sink::Sink) provide support for asynchronous writing of
//!   data.
//! - [Executors](crate::executor) are responsible for running asynchronous
//!   tasks.
//!
//! The crate also contains abstractions for [asynchronous I/O](crate::io) and
//! [cross-task communication](crate::channel).
//!
//! Underlying all of this is the *task system*, which is a form of lightweight
//! threading. Large asynchronous computations are built up using futures,
//! streams and sinks, and then spawned as independent tasks that are run to
//! completion, but *do not block* the thread running them.

#![feature(pin, arbitrary_self_types, futures_api)]

#![no_std]

#![warn(missing_docs, missing_debug_implementations)]
#![deny(bare_trait_objects)]

#![doc(html_root_url = "https://rust-lang-nursery.github.io/futures-api-docs/0.3.0-alpha.2/futures")]

#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))]
#![cfg_attr(feature = "nightly", feature(use_extern_macros))]

#[doc(hidden)] pub use futures_util::core_reexport;

#[doc(hidden)] pub use futures_core::future::Future;
#[doc(hidden)] pub use futures_core::future::TryFuture;
#[doc(hidden)] pub use futures_util::future::FutureExt;
#[doc(hidden)] pub use futures_util::try_future::TryFutureExt;

#[doc(hidden)] pub use futures_core::stream::Stream;
#[doc(hidden)] pub use futures_core::stream::TryStream;
#[doc(hidden)] pub use futures_util::stream::StreamExt;
#[doc(hidden)] pub use futures_util::try_stream::TryStreamExt;

#[doc(hidden)] pub use futures_sink::Sink;
#[doc(hidden)] pub use futures_util::sink::SinkExt;

#[doc(hidden)] pub use futures_core::task::Poll;

// Macro reexports
pub use futures_util::{
    // Error/readiness propagation
    try_ready, try_poll, ready,
};
#[cfg(feature = "std")]
pub use futures_util::{
    // Async-await
    join, try_join, select, pending, poll, spawn, spawn_with_handle,
};

#[cfg(feature = "std")]
pub mod channel {
    //! Cross-task communication.
    //!
    //! Like threads, concurrent tasks sometimes need to communicate with each
    //! other. This module contains two basic abstractions for doing so:
    //!
    //! - [oneshot](crate::channel::oneshot), a way of sending a single value
    //!   from one task to another.
    //! - [mpsc](crate::channel::mpsc), a multi-producer, single-consumer
    //!   channel for sending values between tasks, analogous to the
    //!   similarly-named structure in the standard library.

    pub use futures_channel::{oneshot, mpsc};
}

#[cfg(feature = "compat")]
pub mod compat {
    //! Interop between `futures` 0.1 and 0.3.
    //!

    pub use futures_util::compat::{
        Compat,
        Executor01Future,
        Executor01As03,
        Executor01CompatExt,
        Future01CompatExt,
        Stream01CompatExt,
    };

    #[cfg(feature = "tokio-compat")]
    pub use futures_util::compat::TokioDefaultExecutor;
}

#[cfg(feature = "std")]
pub mod executor {
    //! Task execution.
    //!
    //! All asynchronous computation occurs within an executor, which is
    //! capable of spawning futures as tasks. This module provides several
    //! built-in executors, as well as tools for building your own.
    //!
    //! # Using a thread pool (M:N task scheduling)
    //!
    //! Most of the time tasks should be executed on a [thread
    //! pool](crate::executor::ThreadPool). A small set of worker threads can
    //! handle a very large set of spawned tasks (which are much lighter weight
    //! than threads).
    //!
    //! The simplest way to use a thread pool is to
    //! [`run`](crate::executor::ThreadPool::run) an initial task on it, which
    //! can then spawn further tasks back onto the pool to complete its work:
    //!
    //! ```
    //! #![feature(pin, arbitrary_self_types, futures_api)]
    //! use futures::executor::ThreadPool;
    //! # use futures::future::{Future, lazy};
    //! # let my_app = lazy(|_| 42);
    //!
    //! // assumping `my_app: Future`
    //! ThreadPool::new().expect("Failed to create threadpool").run(my_app);
    //! ```
    //!
    //! The call to [`run`](crate::executor::ThreadPool::run) will block the
    //! current thread until the future defined by `my_app` completes, and will
    //! return the result of that future.
    //!
    //! # Spawning additional tasks
    //!
    //! There are two ways to spawn a task:
    //!
    //! - Spawn onto a "default" execuctor by calling the top-level
    //!   [`spawn`](crate::executor::spawn) function or [pulling the executor
    //!   from the task context](crate::task::Context::executor).
    //! - Spawn onto a specific executor by calling its
    //!   [`spawn_obj`](crate::executor::Executor::spawn_obj) method directly.
    //!
    //! Every task always has an associated default executor, which is usually
    //! the executor on which the task is running.
    //!
    //! # Single-threaded execution
    //!
    //! In addition to thread pools, it's possible to run a task (and the tasks
    //! it spawns) entirely within a single thread via the
    //! [`LocalPool`](crate::executor::LocalPool) executor. Aside from cutting
    //! down on synchronization costs, this executor also makes it possible to
    //! execute non-`Send` tasks, via
    //! [`spawn_local_obj`](crate::executor::LocalExecutor::spawn_local_obj).
    //! The `LocalPool` is best suited for running I/O-bound tasks that do
    //! relatively little work between I/O operations.
    //!
    //! There is also a convenience function,
    //! [`block_on`](crate::executor::block_on), for simply running a future to
    //! completion on the current thread, while routing any spawned tasks
    //! to a global thread pool.

    pub use futures_executor::{
        BlockingStream,
        Enter, EnterError,
        LocalExecutor, LocalPool,
        ThreadPool, ThreadPoolBuilder,
        block_on, block_on_stream, enter,
    };
}

pub mod future {
    //! Asynchronous values.
    //!
    //! This module contains:
    //!
    //! - The [`Future` trait](crate::future::Future).
    //! - The [`FutureExt`](crate::future::FutureExt) trait, which provides
    //!   adapters for chaining and composing futures.
    //! - Top-level future combinators like [`lazy`](crate::future::lazy) which
    //!   creates a future from a closure that defines its return value, and
    //!   [`ready`](crate::future::ready), which constructs a future with an
    //!   immediate defined value.

    pub use futures_core::future::{
        Future, TryFuture,
        FutureObj, LocalFutureObj, UnsafeFutureObj,
    };

    pub use futures_util::future::{
        empty, Empty,
        lazy, Lazy,
        maybe_done, MaybeDone,
        poll_fn, PollFn,
        ready, Ready,

        OptionFuture,

        FutureExt,
        FlattenStream, Flatten, Fuse, Inspect, IntoStream, Join, Join3, Join4,
        Join5, Map, Then, WithExecutor,
    };

    #[cfg(feature = "std")]
    pub use futures_util::future::{
        abortable, Abortable, AbortHandle, AbortRegistration, Aborted,
        // For FutureExt:
        CatchUnwind, Shared

        // ToDo: JoinAll, SelectAll, SelectOk, join_all, select_all, select_ok
    };

    pub use futures_util::try_future::{
        TryFutureExt,
        AndThen, ErrInto, FlattenSink, IntoFuture, MapErr, MapOk, OrElse,
        UnwrapOrElse,
        TryJoin, TryJoin3, TryJoin4, TryJoin5,
    };
}

#[cfg(feature = "std")]
pub mod io {
    //! Asynchronous I/O.
    //!
    //! This module is the asynchronous version of `std::io`. It defines two
    //! traits, [`AsyncRead`](crate::io::AsyncRead) and
    //! [`AsyncWrite`](crate::io::AsyncWrite), which mirror the `Read` and
    //! `Write` traits of the standard library. However, these traits integrate
    //! with the asynchronous task system, so that if an I/O object isn't ready
    //! for reading (or writing), the thread is not blocked, and instead the
    //! current task is queued to be woken when I/O is ready.
    //!
    //! In addition, the [`AsyncReadExt`](crate::io::AsyncReadExt) and
    //! [`AsyncWriteExt`](crate::io::AsyncWriteExt) extension traits offer a
    //! variety of useful combinators for operating with asynchronous I/O
    //! objects, including ways to work with them using futures, streams and
    //! sinks.

    pub use futures_io::{
        Error, Initializer, IoVec, ErrorKind, AsyncRead, AsyncWrite, Result
    };
    pub use futures_util::io::{
        AsyncReadExt, AsyncWriteExt, AllowStdIo, Close, CopyInto, Flush,
        Read, ReadExact, ReadHalf, ReadToEnd, Window, WriteAll, WriteHalf,
    };
}

pub mod prelude {
    //! A "prelude" for crates using the `futures` crate.
    //!
    //! This prelude is similar to the standard library's prelude in that you'll
    //! almost always want to import its entire contents, but unlike the
    //! standard library's prelude you'll have to do so manually:
    //!
    //! ```
    //! use futures::prelude::*;
    //! ```
    //!
    //! The prelude may grow over time as additional items see ubiquitous use.

    pub use crate::future::{self, Future, TryFuture, FutureExt, TryFutureExt};
    pub use crate::stream::{self, Stream, TryStream, StreamExt, TryStreamExt};
    pub use crate::task::{self, Poll, ExecutorExt};
    pub use crate::sink::{self, Sink, SinkExt};

    #[cfg(feature = "std")]
    pub use crate::io::{ AsyncRead, AsyncWrite, AsyncReadExt, AsyncWriteExt };
}

pub mod sink {
    //! Asynchronous sinks.
    //!
    //! This module contains:
    //!
    //! - The [`Sink` trait](crate::sink::Sink), which allows you to
    //!   asynchronously write data.
    //! - The [`SinkExt`](crate::sink::SinkExt) trait, which provides adapters
    //!   for chaining and composing sinks.

    pub use futures_sink::Sink;

    pub use futures_util::sink::{
        Close, Flush, Send, SendAll, SinkErrInto, SinkMapErr, With,
        SinkExt, Fanout, Drain, DrainError, drain,
        // WithFlatMap,
    };

    #[cfg(feature = "std")]
    pub use futures_util::sink::Buffer;
}

pub mod stream {
    //! Asynchronous streams.
    //!
    //! This module contains:
    //!
    //! - The [`Stream` trait](crate::stream::Stream), for objects that can
    //!   asynchronously produce a sequence of values.
    //! - The [`StreamExt`](crate::stream::StreamExt) trait, which provides
    //!   adapters for chaining and composing streams.
    //! - Top-level stream contructors like [`iter_ok`](crate::stream::iter)
    //!   which creates a stream from an iterator, and
    //!   [`futures_unordered`](crate::stream::futures_unordered()), which
    //!   constructs a stream from a collection of futures.

    pub use futures_core::stream::{Stream, TryStream};

    pub use futures_util::stream::{
        iter, Iter,
        repeat, Repeat,
        empty, Empty,
        once, Once,
        poll_fn, PollFn,
        unfold, Unfold,

        StreamExt,
        Chain, Concat, Filter, FilterMap, Flatten, Fold, Forward, ForEach, Fuse,
        StreamFuture, Inspect, Map, Next, Peekable, Select, Skip, SkipWhile,
        Take, TakeWhile, Then, Zip
    };

    #[cfg(feature = "std")]
    pub use futures_util::stream::{
        futures_ordered, FuturesOrdered,
        futures_unordered, FuturesUnordered,

        // For StreamExt:
        BufferUnordered, Buffered, CatchUnwind, Chunks, Collect, SplitStream,
        SplitSink, ReuniteError,

        // ToDo: select_all, SelectAll,
    };

    pub use futures_util::try_stream::{
        TryStreamExt,
        TryNext, TryForEach, ErrInto,
        TryFold, TrySkipWhile,
        // ToDo: AndThen, ErrInto, InspectErr, MapErr, OrElse
    };

    #[cfg(feature = "std")]
    pub use futures_util::try_stream::{
        // For TryStreamExt:
        TryCollect, TryBufferUnordered,
        // ToDo: AndThen, InspectErr, MapErr, OrElse
    };
}

pub mod task {
    //! Tools for working with tasks.
    //!
    //! This module contains:
    //!
    //! - [`Context`](crate::task::Context), which provides contextual data
    //!   present for every task, including a handle for waking up the task.
    //! - [`Waker`](crate::task::Waker), a handle for waking up a task.
    //!
    //! Tasks themselves are generally created by spawning a future onto [an
    //! executor](crate::executor). However, you can manually construct a task
    //! by creating your own `Context` instance, and polling a future with it.
    //!
    //! The remaining types and traits in the module are used for implementing
    //! executors or dealing with synchronization issues around task wakeup.

    pub use futures_core::task::{
        Context, Poll, Executor,
        Waker, LocalWaker, UnsafeWake,
        SpawnErrorKind, SpawnObjError, SpawnLocalObjError,
    };

    #[cfg(feature = "std")]
    pub use futures_core::task::{
        Wake, local_waker, local_waker_from_nonlocal
    };

    pub use futures_util::task::{ExecutorExt, SpawnError};

    #[cfg(feature = "std")]
    pub use futures_util::task::{
        LocalWakerRef, local_waker_ref, local_waker_ref_from_nonlocal, JoinHandle
    };

    #[cfg_attr(
        feature = "nightly",
        cfg(all(target_has_atomic = "cas", target_has_atomic = "ptr"))
    )]
    pub use futures_util::task::AtomicWaker;
}
<commit_msg>Reexport IntoStream from the prelude<commit_after>//! Abstractions for asynchronous programming.
//!
//! This crate provides a number of core abstractions for writing asynchronous
//! code:
//!
//! - [Futures](crate::future::Future) are single eventual values produced by
//!   asychronous computations. Some programming languages (e.g. JavaScript)
//!   call this concept "promise".
//! - [Streams](crate::stream::Stream) represent a series of values
//!   produced asynchronously.
//! - [Sinks](crate::sink::Sink) provide support for asynchronous writing of
//!   data.
//! - [Executors](crate::executor) are responsible for running asynchronous
//!   tasks.
//!
//! The crate also contains abstractions for [asynchronous I/O](crate::io) and
//! [cross-task communication](crate::channel).
//!
//! Underlying all of this is the *task system*, which is a form of lightweight
//! threading. Large asynchronous computations are built up using futures,
//! streams and sinks, and then spawned as independent tasks that are run to
//! completion, but *do not block* the thread running them.

#![feature(pin, arbitrary_self_types, futures_api)]

#![no_std]

#![warn(missing_docs, missing_debug_implementations)]
#![deny(bare_trait_objects)]

#![doc(html_root_url = "https://rust-lang-nursery.github.io/futures-api-docs/0.3.0-alpha.2/futures")]

#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))]
#![cfg_attr(feature = "nightly", feature(use_extern_macros))]

#[doc(hidden)] pub use futures_util::core_reexport;

#[doc(hidden)] pub use futures_core::future::Future;
#[doc(hidden)] pub use futures_core::future::TryFuture;
#[doc(hidden)] pub use futures_util::future::FutureExt;
#[doc(hidden)] pub use futures_util::try_future::TryFutureExt;

#[doc(hidden)] pub use futures_core::stream::Stream;
#[doc(hidden)] pub use futures_core::stream::TryStream;
#[doc(hidden)] pub use futures_util::stream::StreamExt;
#[doc(hidden)] pub use futures_util::try_stream::TryStreamExt;

#[doc(hidden)] pub use futures_sink::Sink;
#[doc(hidden)] pub use futures_util::sink::SinkExt;

#[doc(hidden)] pub use futures_core::task::Poll;

// Macro reexports
pub use futures_util::{
    // Error/readiness propagation
    try_ready, try_poll, ready,
};
#[cfg(feature = "std")]
pub use futures_util::{
    // Async-await
    join, try_join, select, pending, poll, spawn, spawn_with_handle,
};

#[cfg(feature = "std")]
pub mod channel {
    //! Cross-task communication.
    //!
    //! Like threads, concurrent tasks sometimes need to communicate with each
    //! other. This module contains two basic abstractions for doing so:
    //!
    //! - [oneshot](crate::channel::oneshot), a way of sending a single value
    //!   from one task to another.
    //! - [mpsc](crate::channel::mpsc), a multi-producer, single-consumer
    //!   channel for sending values between tasks, analogous to the
    //!   similarly-named structure in the standard library.

    pub use futures_channel::{oneshot, mpsc};
}

#[cfg(feature = "compat")]
pub mod compat {
    //! Interop between `futures` 0.1 and 0.3.
    //!

    pub use futures_util::compat::{
        Compat,
        Executor01Future,
        Executor01As03,
        Executor01CompatExt,
        Future01CompatExt,
        Stream01CompatExt,
    };

    #[cfg(feature = "tokio-compat")]
    pub use futures_util::compat::TokioDefaultExecutor;
}

#[cfg(feature = "std")]
pub mod executor {
    //! Task execution.
    //!
    //! All asynchronous computation occurs within an executor, which is
    //! capable of spawning futures as tasks. This module provides several
    //! built-in executors, as well as tools for building your own.
    //!
    //! # Using a thread pool (M:N task scheduling)
    //!
    //! Most of the time tasks should be executed on a [thread
    //! pool](crate::executor::ThreadPool). A small set of worker threads can
    //! handle a very large set of spawned tasks (which are much lighter weight
    //! than threads).
    //!
    //! The simplest way to use a thread pool is to
    //! [`run`](crate::executor::ThreadPool::run) an initial task on it, which
    //! can then spawn further tasks back onto the pool to complete its work:
    //!
    //! ```
    //! #![feature(pin, arbitrary_self_types, futures_api)]
    //! use futures::executor::ThreadPool;
    //! # use futures::future::{Future, lazy};
    //! # let my_app = lazy(|_| 42);
    //!
    //! // assumping `my_app: Future`
    //! ThreadPool::new().expect("Failed to create threadpool").run(my_app);
    //! ```
    //!
    //! The call to [`run`](crate::executor::ThreadPool::run) will block the
    //! current thread until the future defined by `my_app` completes, and will
    //! return the result of that future.
    //!
    //! # Spawning additional tasks
    //!
    //! There are two ways to spawn a task:
    //!
    //! - Spawn onto a "default" execuctor by calling the top-level
    //!   [`spawn`](crate::executor::spawn) function or [pulling the executor
    //!   from the task context](crate::task::Context::executor).
    //! - Spawn onto a specific executor by calling its
    //!   [`spawn_obj`](crate::executor::Executor::spawn_obj) method directly.
    //!
    //! Every task always has an associated default executor, which is usually
    //! the executor on which the task is running.
    //!
    //! # Single-threaded execution
    //!
    //! In addition to thread pools, it's possible to run a task (and the tasks
    //! it spawns) entirely within a single thread via the
    //! [`LocalPool`](crate::executor::LocalPool) executor. Aside from cutting
    //! down on synchronization costs, this executor also makes it possible to
    //! execute non-`Send` tasks, via
    //! [`spawn_local_obj`](crate::executor::LocalExecutor::spawn_local_obj).
    //! The `LocalPool` is best suited for running I/O-bound tasks that do
    //! relatively little work between I/O operations.
    //!
    //! There is also a convenience function,
    //! [`block_on`](crate::executor::block_on), for simply running a future to
    //! completion on the current thread, while routing any spawned tasks
    //! to a global thread pool.

    pub use futures_executor::{
        BlockingStream,
        Enter, EnterError,
        LocalExecutor, LocalPool,
        ThreadPool, ThreadPoolBuilder,
        block_on, block_on_stream, enter,
    };
}

pub mod future {
    //! Asynchronous values.
    //!
    //! This module contains:
    //!
    //! - The [`Future` trait](crate::future::Future).
    //! - The [`FutureExt`](crate::future::FutureExt) trait, which provides
    //!   adapters for chaining and composing futures.
    //! - Top-level future combinators like [`lazy`](crate::future::lazy) which
    //!   creates a future from a closure that defines its return value, and
    //!   [`ready`](crate::future::ready), which constructs a future with an
    //!   immediate defined value.

    pub use futures_core::future::{
        Future, TryFuture,
        FutureObj, LocalFutureObj, UnsafeFutureObj,
    };

    pub use futures_util::future::{
        empty, Empty,
        lazy, Lazy,
        maybe_done, MaybeDone,
        poll_fn, PollFn,
        ready, Ready,

        OptionFuture,

        FutureExt,
        FlattenStream, Flatten, Fuse, Inspect, IntoStream, Join, Join3, Join4,
        Join5, Map, Then, WithExecutor,
    };

    #[cfg(feature = "std")]
    pub use futures_util::future::{
        abortable, Abortable, AbortHandle, AbortRegistration, Aborted,
        // For FutureExt:
        CatchUnwind, Shared

        // ToDo: JoinAll, SelectAll, SelectOk, join_all, select_all, select_ok
    };

    pub use futures_util::try_future::{
        TryFutureExt,
        AndThen, ErrInto, FlattenSink, IntoFuture, MapErr, MapOk, OrElse,
        UnwrapOrElse,
        TryJoin, TryJoin3, TryJoin4, TryJoin5,
    };
}

#[cfg(feature = "std")]
pub mod io {
    //! Asynchronous I/O.
    //!
    //! This module is the asynchronous version of `std::io`. It defines two
    //! traits, [`AsyncRead`](crate::io::AsyncRead) and
    //! [`AsyncWrite`](crate::io::AsyncWrite), which mirror the `Read` and
    //! `Write` traits of the standard library. However, these traits integrate
    //! with the asynchronous task system, so that if an I/O object isn't ready
    //! for reading (or writing), the thread is not blocked, and instead the
    //! current task is queued to be woken when I/O is ready.
    //!
    //! In addition, the [`AsyncReadExt`](crate::io::AsyncReadExt) and
    //! [`AsyncWriteExt`](crate::io::AsyncWriteExt) extension traits offer a
    //! variety of useful combinators for operating with asynchronous I/O
    //! objects, including ways to work with them using futures, streams and
    //! sinks.

    pub use futures_io::{
        Error, Initializer, IoVec, ErrorKind, AsyncRead, AsyncWrite, Result
    };
    pub use futures_util::io::{
        AsyncReadExt, AsyncWriteExt, AllowStdIo, Close, CopyInto, Flush,
        Read, ReadExact, ReadHalf, ReadToEnd, Window, WriteAll, WriteHalf,
    };
}

pub mod prelude {
    //! A "prelude" for crates using the `futures` crate.
    //!
    //! This prelude is similar to the standard library's prelude in that you'll
    //! almost always want to import its entire contents, but unlike the
    //! standard library's prelude you'll have to do so manually:
    //!
    //! ```
    //! use futures::prelude::*;
    //! ```
    //!
    //! The prelude may grow over time as additional items see ubiquitous use.

    pub use crate::future::{self, Future, TryFuture, FutureExt, TryFutureExt};
    pub use crate::stream::{self, Stream, TryStream, StreamExt, TryStreamExt};
    pub use crate::task::{self, Poll, ExecutorExt};
    pub use crate::sink::{self, Sink, SinkExt};

    #[cfg(feature = "std")]
    pub use crate::io::{ AsyncRead, AsyncWrite, AsyncReadExt, AsyncWriteExt };
}

pub mod sink {
    //! Asynchronous sinks.
    //!
    //! This module contains:
    //!
    //! - The [`Sink` trait](crate::sink::Sink), which allows you to
    //!   asynchronously write data.
    //! - The [`SinkExt`](crate::sink::SinkExt) trait, which provides adapters
    //!   for chaining and composing sinks.

    pub use futures_sink::Sink;

    pub use futures_util::sink::{
        Close, Flush, Send, SendAll, SinkErrInto, SinkMapErr, With,
        SinkExt, Fanout, Drain, DrainError, drain,
        // WithFlatMap,
    };

    #[cfg(feature = "std")]
    pub use futures_util::sink::Buffer;
}

pub mod stream {
    //! Asynchronous streams.
    //!
    //! This module contains:
    //!
    //! - The [`Stream` trait](crate::stream::Stream), for objects that can
    //!   asynchronously produce a sequence of values.
    //! - The [`StreamExt`](crate::stream::StreamExt) trait, which provides
    //!   adapters for chaining and composing streams.
    //! - Top-level stream contructors like [`iter_ok`](crate::stream::iter)
    //!   which creates a stream from an iterator, and
    //!   [`futures_unordered`](crate::stream::futures_unordered()), which
    //!   constructs a stream from a collection of futures.

    pub use futures_core::stream::{Stream, TryStream};

    pub use futures_util::stream::{
        iter, Iter,
        repeat, Repeat,
        empty, Empty,
        once, Once,
        poll_fn, PollFn,
        unfold, Unfold,

        StreamExt,
        Chain, Concat, Filter, FilterMap, Flatten, Fold, Forward, ForEach, Fuse,
        StreamFuture, Inspect, Map, Next, Peekable, Select, Skip, SkipWhile,
        Take, TakeWhile, Then, Zip
    };

    #[cfg(feature = "std")]
    pub use futures_util::stream::{
        futures_ordered, FuturesOrdered,
        futures_unordered, FuturesUnordered,

        // For StreamExt:
        BufferUnordered, Buffered, CatchUnwind, Chunks, Collect, SplitStream,
        SplitSink, ReuniteError,

        // ToDo: select_all, SelectAll,
    };

    pub use futures_util::try_stream::{
        TryStreamExt,
        TryNext, TryForEach, ErrInto,
        TryFold, TrySkipWhile,
        IntoStream,
        // ToDo: AndThen, ErrInto, InspectErr, MapErr, OrElse
    };

    #[cfg(feature = "std")]
    pub use futures_util::try_stream::{
        // For TryStreamExt:
        TryCollect, TryBufferUnordered,
        // ToDo: AndThen, InspectErr, MapErr, OrElse
    };
}

pub mod task {
    //! Tools for working with tasks.
    //!
    //! This module contains:
    //!
    //! - [`Context`](crate::task::Context), which provides contextual data
    //!   present for every task, including a handle for waking up the task.
    //! - [`Waker`](crate::task::Waker), a handle for waking up a task.
    //!
    //! Tasks themselves are generally created by spawning a future onto [an
    //! executor](crate::executor). However, you can manually construct a task
    //! by creating your own `Context` instance, and polling a future with it.
    //!
    //! The remaining types and traits in the module are used for implementing
    //! executors or dealing with synchronization issues around task wakeup.

    pub use futures_core::task::{
        Context, Poll, Executor,
        Waker, LocalWaker, UnsafeWake,
        SpawnErrorKind, SpawnObjError, SpawnLocalObjError,
    };

    #[cfg(feature = "std")]
    pub use futures_core::task::{
        Wake, local_waker, local_waker_from_nonlocal
    };

    pub use futures_util::task::{ExecutorExt, SpawnError};

    #[cfg(feature = "std")]
    pub use futures_util::task::{
        LocalWakerRef, local_waker_ref, local_waker_ref_from_nonlocal, JoinHandle
    };

    #[cfg_attr(
        feature = "nightly",
        cfg(all(target_has_atomic = "cas", target_has_atomic = "ptr"))
    )]
    pub use futures_util::task::AtomicWaker;
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(afl_coverage_plugin)]

extern crate afl_coverage;
extern crate tar;
extern crate nom;

use tar::*;
use nom::IResult;
use std::fs::File;
use std::io::{self, Read};

fn main() {
    let mut contents: Vec<u8> = Vec::new();
    let result = io::stdin().read_to_end(&mut contents).unwrap();
    let tar = &contents[..];

    match parse_tar(tar) {
        IResult::Done(_, entries) => {
            for e in entries.iter() {
                println!("{:?}", e);
            }
        }
        e  => {
            println!("error or incomplete: {:?}", e);
            panic!("cannot parse tar archive");
        }
    }
}
<commit_msg>remove debug prints<commit_after>#![feature(plugin)]
#![plugin(afl_coverage_plugin)]

extern crate afl_coverage;
extern crate tar;
extern crate nom;

use tar::*;
use nom::IResult;
use std::fs::File;
use std::io::{self, Read};

fn main() {
    let mut contents: Vec<u8> = Vec::new();
    let result = io::stdin().read_to_end(&mut contents).unwrap();
    let tar = &contents[..];

    match parse_tar(tar) {
        IResult::Done(_, entries) => {
            for e in entries.iter() {
                //println!("{:?}", e);
            }
        }
        e  => {
            //println!("error or incomplete: {:?}", e);
            //panic!("cannot parse tar archive");
        }
    }
}
<|endoftext|>


<commit_before>use std::io::prelude::*;
use std::process::{Command, Stdio};
use std::io::{Error,ErrorKind};
use std::io::BufReader;
use std::convert::AsRef;

const CONTENT_TYPE: &'static str = "Content-Type: text/html\n";

pub fn send_new<'a ,T: AsRef<[&'a str]>>(from_address:&str, to_address: T, subject_text: &str, body_text: &str) -> Result<(),Error> {

    let address: &[&str] = to_address.as_ref();

    let mut cmd = Command::new("sendmail");
    cmd.args(address)
        .stdin(Stdio::piped())
        .stdout(Stdio::null())
        .stderr(Stdio::piped());
    let mut process = cmd.spawn()?;

    { // required because of process.wait()
        let mut stdin = process.stdin.as_mut().ok_or(Error::new(ErrorKind::BrokenPipe, "no stdin"))?;

        writeln!(&mut stdin,"From: {}",from_address)?;
        writeln!(&mut stdin,"To: {}",address.join(","))?;
        writeln!(&mut stdin,"Subject: {}",subject_text)?;
        stdin.write_all(CONTENT_TYPE.as_bytes())?;
        stdin.write_all(body_text.as_bytes())?;
        stdin.flush()?;
    }

    process.wait()?;

    //let mut stdout_buffer = BufReader::new(process.stdout.take()?);
    let mut stderr_buffer = BufReader::new(process.stderr.ok_or(Error::new(ErrorKind::BrokenPipe, "no stderr"))?);

    let mut stderr: String = String::new();
    stderr_buffer.read_to_string(&mut stderr)?;

    if stderr.is_empty() {
        Ok(())
    } else {
        Err(Error::new(ErrorKind::Other, format!("sendmail returned: {}",stderr)))
    }
}
<commit_msg>change to just send<commit_after>use std::io::prelude::*;
use std::process::{Command, Stdio};
use std::io::{Error,ErrorKind};
use std::io::BufReader;
use std::convert::AsRef;

const CONTENT_TYPE: &'static str = "Content-Type: text/html\n";

pub fn send<'a ,T: AsRef<[&'a str]>>(from_address:&str, to_address: T, subject_text: &str, body_text: &str) -> Result<(),Error> {

    let address: &[&str] = to_address.as_ref();

    let mut cmd = Command::new("sendmail");
    cmd.args(address)
        .stdin(Stdio::piped())
        .stdout(Stdio::null())
        .stderr(Stdio::piped());
    let mut process = cmd.spawn()?;

    { // required because of process.wait()
        let mut stdin = process.stdin.as_mut().ok_or(Error::new(ErrorKind::BrokenPipe, "no stdin"))?;

        writeln!(&mut stdin,"From: {}",from_address)?;
        writeln!(&mut stdin,"To: {}",address.join(","))?;
        writeln!(&mut stdin,"Subject: {}",subject_text)?;
        stdin.write_all(CONTENT_TYPE.as_bytes())?;
        stdin.write_all(body_text.as_bytes())?;
        stdin.flush()?;
    }

    process.wait()?;

    //let mut stdout_buffer = BufReader::new(process.stdout.take()?);
    let mut stderr_buffer = BufReader::new(process.stderr.ok_or(Error::new(ErrorKind::BrokenPipe, "no stderr"))?);

    let mut stderr: String = String::new();
    stderr_buffer.read_to_string(&mut stderr)?;

    if stderr.is_empty() {
        Ok(())
    } else {
        Err(Error::new(ErrorKind::Other, format!("sendmail returned: {}",stderr)))
    }
}
<|endoftext|>


<commit_before>//! Binary lambda calculus execution

use binary_encoding::{from_binary};
use lambda_encoding::{encode, decode};
use lambda_calculus::reduction::beta_full;
use self::Error::*;

/// An error that can occur during blc execution.
#[derive(Debug, PartialEq)]
pub enum Error {
    InvalidProgram
}

/// Executes a binary lambda calculus program, optionally feeding it the given argument.
///
/// # Example
/// ```
/// use blc::execution::run;
///
/// let reverse = b"00 01 01 10 01 00 01 10 10 00 00 00 00 01 01 110\
///                 01 11110 11110 00 01 01 10 11110 110 00 00 10";
///
/// assert_eq!(run(&*reverse, Some(b"herp derp")), Ok("pred preh".into()));
/// ```
pub fn run(blc_program: &[u8], blc_argument: Option<&[u8]>) -> Result<String, Error> {
    let program = from_binary(blc_program);
    if program.is_err() { return Err(InvalidProgram) }

    let calculation = if blc_argument.is_some() {
        let argument = encode(blc_argument.unwrap());
        beta_full(program.unwrap().app(argument)) // safe
    } else {
        beta_full(program.unwrap())
    };

    Ok(decode(calculation))
}

#[cfg(test)]
mod test {
    use super::*;
    use binary_encoding::decompress;

    #[test]
    fn id() {
        let id_compressed = b" ";
        let id_blc        = decompress(&*id_compressed);
        let input         = b"herp derp";

        assert_eq!(run(&*id_blc, Some(&*input)).unwrap(), "herp derp".to_owned());
    }

    #[test]
    fn sort() {
        let sort_compressed =
            [0x15, 0x46, 0x84, 0x06, 0x05, 0x46, 0x81, 0x60, 0x15, 0xfb, 0xec, 0x2f, 0x80, 0x01,
             0x5b, 0xf9, 0x7f, 0x0b, 0x7e, 0xf7, 0x2f, 0xec, 0x2d, 0xfb, 0x80, 0x56, 0x05, 0xfd,
             0x85, 0xbb, 0x76, 0x11, 0x5d, 0x50, 0x5c, 0x00, 0xbe, 0x7f, 0xc1, 0x2b, 0xff, 0x0f,
             0xfc, 0x2c, 0x1b, 0x72, 0xbf, 0xf0, 0xff, 0xc2, 0xc1, 0x6d, 0x34, 0x50, 0x40];

        let sort_blc = decompress(&sort_compressed);
        let input  = b"3241";

        assert_eq!(run(&*sort_blc, Some(&*input)).unwrap(), "1234".to_owned());
    }

    #[test]
    fn inflating() {
        // program code from http://www.ioccc.org/2012/tromp/inflate.Blc
        let inflate_compressed =
            [0x44, 0x44, 0x68, 0x16, 0x01, 0x79, 0x1a, 0x00, 0x16, 0x7f, 0xfb, 0xcb, 0xcf, 0xdf,
             0x65, 0xfb, 0xed, 0x0f, 0x3c, 0xe7, 0x3c, 0xf3, 0xc2, 0xd8, 0x20, 0x58, 0x2c, 0x0b,
             0x06, 0xc0];

        let inflate_blc = decompress(&inflate_compressed);
        let s_compressed = [0x1, 0x7a, 0x74];

        assert_eq!(run(&*inflate_blc, Some(&s_compressed[..])).unwrap(), "000000010111101001110100".to_owned());
    }

    #[test]
    fn deflating() {
        // program code from http://www.ioccc.org/2012/tromp/deflate.Blc
        let deflate_compressed =
            [0x44, 0x68, 0x16, 0x05, 0x7e, 0x01, 0x17, 0x00, 0xbe, 0x55, 0xff, 0xf0, 0x0d, 0xc1,
             0x8b, 0xb2, 0xc1, 0xb0, 0xf8, 0x7c, 0x2d, 0xd8, 0x05, 0x9e, 0x09, 0x7f, 0xbf, 0xb1,
             0x48, 0x39, 0xce, 0x81, 0xce, 0x80];

        let deflate_blc = decompress(&deflate_compressed);
        let s_blc = b"00000001011110100111010";

        assert_eq!(run(&*deflate_blc, Some(&s_blc[..])).unwrap().as_bytes(), [0x1, 0x7a, 0x74]);
    }
/*
    #[test] /* WIP; this one parses properly, but doesn't return the expected result */
    fn hilbert() {
        // program code from http://www.ioccc.org/2012/tromp/hilbert.Blc
        let hilbert_compressed =
            [0x18, 0x18, 0x18, 0x18, 0x11, 0x11, 0x54, 0x68, 0x06, 0x04, 0x15, 0x5f, 0xf0, 0x41,
             0x9d, 0xf9, 0xde, 0x16, 0xff, 0xfe, 0x5f, 0x3f, 0xef, 0xf6, 0x15, 0xff, 0x94, 0x68,
             0x40, 0x58, 0x11, 0x7e, 0x05, 0xcb, 0xfe, 0xbc, 0xbf, 0xee, 0x86, 0xcb, 0x94, 0x68,
             0x16, 0x00, 0x5c, 0x0b, 0xfa, 0xcb, 0xfb, 0xf7, 0x1a, 0x85, 0xe0, 0x5c, 0xf4, 0x14,
             0xd5, 0xfe, 0x08, 0x18, 0x0b, 0x04, 0x8d, 0x08, 0x00, 0xe0, 0x78, 0x01, 0x64, 0x45,
             0xff, 0xe5, 0xff, 0x7f, 0xff, 0xfe, 0x5f, 0xff, 0x2f, 0xc0, 0x2f, 0x7a, 0xd9, 0x7f,
             0x5b, 0xff, 0xff, 0xfb, 0xff, 0xfc, 0xaa, 0xff, 0xf7, 0x81, 0x7f, 0xfa, 0xdf, 0x76,
             0x69, 0x54, 0x68, 0x06, 0x01, 0x57, 0xf7, 0xe1, 0x60, 0x5c, 0x13, 0xfe, 0x80, 0xb2,
             0x2c, 0x18, 0x58, 0x1b, 0xfe, 0x5c, 0x10, 0x42, 0xff, 0x80, 0x5d, 0xee, 0xc0, 0x6c,
             0x2c, 0x0c, 0x06, 0x08, 0x19, 0x1a, 0x00, 0x16, 0x7f, 0xbc, 0xbc, 0xfd, 0xf6, 0x5f,
             0x7c, 0x0a, 0x20];

        let hilbert_blc = decompress(&hilbert_compressed);
        let arg = b"1234";

        assert_eq!(run(&hilbert_blc[..], &arg[..]), Ok("WIP".into()));
    }
*/
/*
    #[test] /* WIP; this just returns λ1 */
    fn brainfuck() {
        // program code from http://www.ioccc.org/2012/tromp/bf.Blc
        let bf_interpreter_compressed =
            [0x44, 0x51, 0xa1, 0x01, 0x84, 0x55, 0xd5, 0x02, 0xb7, 0x70, 0x30, 0x22, 0xff, 0x32,
             0xf0, 0x00, 0xbf, 0xf9, 0x85, 0x7f, 0x5e, 0xe1, 0x6f, 0x95, 0x7f, 0x7d, 0xee, 0xc0,
             0xe5, 0x54, 0x68, 0x00, 0x58, 0x55, 0xfd, 0xfb, 0xe0, 0x45, 0x57, 0xfd, 0xeb, 0xfb,
             0xf0, 0xb6, 0xf0, 0x2f, 0xd6, 0x07, 0xe1, 0x6f, 0x73, 0xd7, 0xf1, 0x14, 0xbc, 0xc0,
             0x0b, 0xff, 0x2e, 0x1f, 0xa1, 0x6f, 0x66, 0x17, 0xe8, 0x5b, 0xef, 0x2f, 0xcf, 0xff,
             0x13, 0xff, 0xe1, 0xca, 0x34, 0x20, 0x0a, 0xc8, 0xd0, 0x0b, 0x99, 0xee, 0x1f, 0xe5,
             0xff, 0x7f, 0x5a, 0x6a, 0x1f, 0xff, 0x0f, 0xff, 0x87, 0x9d, 0x04, 0xd0, 0xab, 0x00,
             0x05, 0xdb, 0x23, 0x40, 0xb7, 0x3b, 0x28, 0xcc, 0xc0, 0xb0, 0x6c, 0x0e, 0x74, 0x10];

        let bf_interpreter_blc = decompress(&bf_interpreter_compressed);
        let bf_hello =
            b"++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.";

        assert_eq!(run(&bf_interpreter_blc, &bf_hello[..]), Ok("Hello World!".into()));
    }
*/
}
<commit_msg>different input modes for BLC execution<commit_after>//! Binary lambda calculus execution

use binary_encoding::{from_binary};
use lambda_encoding::{encode, decode};
use lambda_calculus::reduction::beta_full;
use self::Error::*;
use self::Input::*;

/// An error that can occur during BLC execution.
#[derive(Debug, PartialEq)]
pub enum Error {
    InvalidProgram,
    InvalidArgument
}

/// The type of input for BLC execution.
pub enum Input<'a> {
    /// no input parameter
    Nothing,
    /// BLC input
    Binary(&'a [u8]),
    /// unencoded byte input
    Bytes(&'a [u8])
}

/// Executes a binary lambda calculus program, optionally feeding it the given argument.
///
/// # Example
/// ```
/// use blc::execution::run;
///
/// let reverse = b"00 01 01 10 01 00 01 10 10 00 00 00 00 01 01 110\
///                 01 11110 11110 00 01 01 10 11110 110 00 00 10";
///
/// assert_eq!(run(&*reverse, Some(b"herp derp")), Ok("pred preh".into()));
/// ```
pub fn run(blc_program: &[u8], input: Input) -> Result<String, Error> {
    let program = from_binary(blc_program);
    if program.is_err() { return Err(InvalidProgram) }
    let program = program.unwrap(); // safe

    let calculation = match input {
        Nothing     => beta_full(program),
        Bytes(arg)  => beta_full(app!(program, encode(arg))),
        Binary(arg) => {
            let arg = from_binary(arg);
            if arg.is_ok() {
                beta_full(app!(program, arg.unwrap())) // safe
            } else {
                return Err(InvalidArgument)
            }
        }
    };

    Ok(decode(calculation))
}

#[cfg(test)]
mod test {
    use super::*;
    use binary_encoding::decompress;

    #[test]
    fn id() {
        let id_compressed = b" ";
        let id_blc        = decompress(&*id_compressed);
        let input         = b"herp derp";

        assert_eq!(run(&*id_blc, Bytes(&*input)).unwrap(), "herp derp".to_owned());
    }

    #[test]
    fn sort() {
        let sort_compressed =
            [0x15, 0x46, 0x84, 0x06, 0x05, 0x46, 0x81, 0x60, 0x15, 0xfb, 0xec, 0x2f, 0x80, 0x01,
             0x5b, 0xf9, 0x7f, 0x0b, 0x7e, 0xf7, 0x2f, 0xec, 0x2d, 0xfb, 0x80, 0x56, 0x05, 0xfd,
             0x85, 0xbb, 0x76, 0x11, 0x5d, 0x50, 0x5c, 0x00, 0xbe, 0x7f, 0xc1, 0x2b, 0xff, 0x0f,
             0xfc, 0x2c, 0x1b, 0x72, 0xbf, 0xf0, 0xff, 0xc2, 0xc1, 0x6d, 0x34, 0x50, 0x40];

        let sort_blc = decompress(&sort_compressed);
        let input  = b"3241";

        assert_eq!(run(&*sort_blc, Bytes(&*input)).unwrap(), "1234".to_owned());
    }

    #[test]
    fn inflating() {
        // program code from http://www.ioccc.org/2012/tromp/inflate.Blc
        let inflate_compressed =
            [0x44, 0x44, 0x68, 0x16, 0x01, 0x79, 0x1a, 0x00, 0x16, 0x7f, 0xfb, 0xcb, 0xcf, 0xdf,
             0x65, 0xfb, 0xed, 0x0f, 0x3c, 0xe7, 0x3c, 0xf3, 0xc2, 0xd8, 0x20, 0x58, 0x2c, 0x0b,
             0x06, 0xc0];

        let inflate_blc = decompress(&inflate_compressed);
        let s_compressed = [0x1, 0x7a, 0x74];

        assert_eq!(run(&*inflate_blc, Bytes(&s_compressed[..])).unwrap(), "000000010111101001110100".to_owned());
    }

    #[test]
    fn deflating() {
        // program code from http://www.ioccc.org/2012/tromp/deflate.Blc
        let deflate_compressed =
            [0x44, 0x68, 0x16, 0x05, 0x7e, 0x01, 0x17, 0x00, 0xbe, 0x55, 0xff, 0xf0, 0x0d, 0xc1,
             0x8b, 0xb2, 0xc1, 0xb0, 0xf8, 0x7c, 0x2d, 0xd8, 0x05, 0x9e, 0x09, 0x7f, 0xbf, 0xb1,
             0x48, 0x39, 0xce, 0x81, 0xce, 0x80];

        let deflate_blc = decompress(&deflate_compressed);
        let s_blc = b"00000001011110100111010";

        assert_eq!(run(&*deflate_blc, Bytes(&s_blc[..])).unwrap().as_bytes(), [0x1, 0x7a, 0x74]);
    }
/*
    #[test] /* WIP; this one parses properly, but doesn't return the expected result */
    fn hilbert() {
        // program code from http://www.ioccc.org/2012/tromp/hilbert.Blc
        let hilbert_compressed =
            [0x18, 0x18, 0x18, 0x18, 0x11, 0x11, 0x54, 0x68, 0x06, 0x04, 0x15, 0x5f, 0xf0, 0x41,
             0x9d, 0xf9, 0xde, 0x16, 0xff, 0xfe, 0x5f, 0x3f, 0xef, 0xf6, 0x15, 0xff, 0x94, 0x68,
             0x40, 0x58, 0x11, 0x7e, 0x05, 0xcb, 0xfe, 0xbc, 0xbf, 0xee, 0x86, 0xcb, 0x94, 0x68,
             0x16, 0x00, 0x5c, 0x0b, 0xfa, 0xcb, 0xfb, 0xf7, 0x1a, 0x85, 0xe0, 0x5c, 0xf4, 0x14,
             0xd5, 0xfe, 0x08, 0x18, 0x0b, 0x04, 0x8d, 0x08, 0x00, 0xe0, 0x78, 0x01, 0x64, 0x45,
             0xff, 0xe5, 0xff, 0x7f, 0xff, 0xfe, 0x5f, 0xff, 0x2f, 0xc0, 0x2f, 0x7a, 0xd9, 0x7f,
             0x5b, 0xff, 0xff, 0xfb, 0xff, 0xfc, 0xaa, 0xff, 0xf7, 0x81, 0x7f, 0xfa, 0xdf, 0x76,
             0x69, 0x54, 0x68, 0x06, 0x01, 0x57, 0xf7, 0xe1, 0x60, 0x5c, 0x13, 0xfe, 0x80, 0xb2,
             0x2c, 0x18, 0x58, 0x1b, 0xfe, 0x5c, 0x10, 0x42, 0xff, 0x80, 0x5d, 0xee, 0xc0, 0x6c,
             0x2c, 0x0c, 0x06, 0x08, 0x19, 0x1a, 0x00, 0x16, 0x7f, 0xbc, 0xbc, 0xfd, 0xf6, 0x5f,
             0x7c, 0x0a, 0x20];

        let hilbert_blc = decompress(&hilbert_compressed);
        let arg = b"1234";

        assert_eq!(run(&hilbert_blc[..], Bytes(&arg[..])), Ok("WIP".into()));
    }
*/
/*
    #[test] /* WIP; this just returns λ1 */
    fn brainfuck() {
        // program code from http://www.ioccc.org/2012/tromp/bf.Blc
        let bf_interpreter_compressed =
            [0x44, 0x51, 0xa1, 0x01, 0x84, 0x55, 0xd5, 0x02, 0xb7, 0x70, 0x30, 0x22, 0xff, 0x32,
             0xf0, 0x00, 0xbf, 0xf9, 0x85, 0x7f, 0x5e, 0xe1, 0x6f, 0x95, 0x7f, 0x7d, 0xee, 0xc0,
             0xe5, 0x54, 0x68, 0x00, 0x58, 0x55, 0xfd, 0xfb, 0xe0, 0x45, 0x57, 0xfd, 0xeb, 0xfb,
             0xf0, 0xb6, 0xf0, 0x2f, 0xd6, 0x07, 0xe1, 0x6f, 0x73, 0xd7, 0xf1, 0x14, 0xbc, 0xc0,
             0x0b, 0xff, 0x2e, 0x1f, 0xa1, 0x6f, 0x66, 0x17, 0xe8, 0x5b, 0xef, 0x2f, 0xcf, 0xff,
             0x13, 0xff, 0xe1, 0xca, 0x34, 0x20, 0x0a, 0xc8, 0xd0, 0x0b, 0x99, 0xee, 0x1f, 0xe5,
             0xff, 0x7f, 0x5a, 0x6a, 0x1f, 0xff, 0x0f, 0xff, 0x87, 0x9d, 0x04, 0xd0, 0xab, 0x00,
             0x05, 0xdb, 0x23, 0x40, 0xb7, 0x3b, 0x28, 0xcc, 0xc0, 0xb0, 0x6c, 0x0e, 0x74, 0x10];

        let bf_interpreter_blc = decompress(&bf_interpreter_compressed);
        let bf_hello =
            b"++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.";

        assert_eq!(run(&bf_interpreter_blc, Bytes(&bf_hello[..])), Ok("Hello World!".into()));
    }
*/
}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/Factorial

use std::iter::range_inclusive;

// Calculate the factorial using recursion
fn factorial_recursive (n: uint) -> uint {
	match n {
		0 => 1,
		_ => n * factorial_recursive(n-1)
	}
}

// Calculate the factorial using a fold
fn factorial_iterative(n: uint) -> uint {
	range_inclusive(1, n).fold(1, |p, t| p * t)
}

// Calculate the factorial using a for loop
fn factorial_loop(n: uint) -> uint {
    let mut fac = 1;
    for x in range_inclusive(1, n) {
        fac *= x;
    }
    fac
}

#[cfg(not(test))]
fn main () {
	for i in range(1u, 10) {
		println!("{}", factorial_recursive(i))
	}
	for i in range(1u, 10) {
		println!("{}", factorial_iterative(i))
	}
    for i in range(1u, 10) {
        println!("{}", factorial_loop(i));
    }
}

// Some tests and benchmarks
#[cfg(test)]
mod tests {
    extern crate test;
    use self::test::Bencher;
    use super::{factorial_recursive, factorial_iterative, factorial_loop};

    // Tests
    #[test]
    fn test_fac_recursive() {
        assert!(factorial_recursive(0) == 1);
        assert!(factorial_recursive(10) == 3628800);
    }

    #[test]
    fn test_fac_iterative() {
        assert!(factorial_iterative(0) == 1);
        assert!(factorial_iterative(10) == 3628800);
    }

    #[test]
    fn test_fac_loop() {
        assert!(factorial_loop(0) == 1);
        assert!(factorial_loop(10) == 3628800);
    }

    // Benchmarks
    #[bench]
    fn bench_fac_recursive(b: &mut Bencher) {
        b.iter(|| {
            test::black_box(factorial_recursive(10));
        });
    }

    #[bench]
    fn bench_fac_iterative(b: &mut Bencher) {
        b.iter(|| {
            test::black_box(factorial_iterative(10));
        });
    }

    #[bench]
    fn bench_fac_loop(b: &mut Bencher) {
        b.iter(|| {
            test::black_box(factorial_loop(10));
        });
    }
}
<commit_msg>factorial: style<commit_after>// Implements http://rosettacode.org/wiki/Factorial

use std::iter::range_inclusive;

// Calculate the factorial using recursion
fn factorial_recursive (n: uint) -> uint {
	match n {
		0 => 1,
		_ => n * factorial_recursive(n-1)
	}
}

// Calculate the factorial using a fold
fn factorial_iterative(n: uint) -> uint {
	range_inclusive(1, n).fold(1, |p, t| p * t)
}

// Calculate the factorial using a for loop
fn factorial_loop(n: uint) -> uint {
    let mut fac = 1;
    for x in range_inclusive(1, n) {
        fac *= x;
    }
    fac
}

#[cfg(not(test))]
fn main () {
    let fs = vec![("Recursive", factorial_recursive),
                  ("Iterative", factorial_iterative),
                  ("Looooooop", factorial_loop)];
	for (name, f) in fs.move_iter() {
        println!("---------\n{}", name)
        for i in range(1u, 10) {
            println!("{}", f(i))
        }
    }
}

// Some tests and benchmarks
#[cfg(test)]
mod tests {
    extern crate test;
    use self::test::Bencher;
    use super::{factorial_recursive, factorial_iterative, factorial_loop};

    // Tests
    fn t(f: |uint| -> uint) {
        assert_eq!(f(0), 1);
        assert_eq!(f(1), 1);
        assert_eq!(f(2), 2);
        assert_eq!(f(3), 6);
        assert_eq!(f(4), 24);
        assert_eq!(f(5), 120);
        assert_eq!(f(6), 720);
        assert_eq!(f(7), 5040);
        assert_eq!(f(8), 40320);
        assert_eq!(f(9), 362880);
        assert_eq!(f(10), 3628800);
    }

    #[test]
    fn test_fac_recursive() {
        t(factorial_recursive)
    }

    #[test]
    fn test_fac_iterative() {
        t(factorial_iterative)
    }

    #[test]
    fn test_fac_loop() {
        t(factorial_loop)
    }

    // Benchmarks
    #[bench]
    fn bench_fac_recursive(b: &mut Bencher) {
        b.iter(|| {
            test::black_box(factorial_recursive(10));
        });
    }

    #[bench]
    fn bench_fac_iterative(b: &mut Bencher) {
        b.iter(|| {
            test::black_box(factorial_iterative(10));
        });
    }

    #[bench]
    fn bench_fac_loop(b: &mut Bencher) {
        b.iter(|| {
            test::black_box(factorial_loop(10));
        });
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::io::{Read, Write, Error};
use std::path::{Path, PathBuf};
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::os::unix::io::AsRawFd;

use nix;
use nix::fcntl::{flock, FlockArg};

use path_util::PathExt;

pub struct Lock {
    file: fs::File,
}

pub fn read_visible_entries(dir: &Path) -> Result<Vec<PathBuf>, Error> {
    let mut res = vec!();
    for entry_ in try!(fs::read_dir(dir)) {
        let entry = try!(entry_);
        if !entry.file_name()[..].to_str().map(|x| x.starts_with("."))
            .unwrap_or(false)
        {
            res.push(entry.path().to_path_buf());
        }
    }
    Ok(res)
}

pub fn create_dir<P:AsRef<Path>>(path: P, recursive: bool) -> Result<(), Error>
{
    let path = path.as_ref();
    if path.is_dir() {
        return Ok(())
    }
    if recursive {
        match path.parent() {
            Some(p) if p != path => try!(create_dir(p, true)),
            _ => {}
        }
    }
    try!(fs::create_dir(path));
    try!(fs::set_permissions(path, fs::Permissions::from_mode(0o755)));
    Ok(())
}

pub fn create_dir_mode(path: &Path, mode: u32) -> Result<(), Error> {
    if path.is_dir() {
        return Ok(())
    }
    try!(fs::create_dir(path));
    try!(fs::set_permissions(path, fs::Permissions::from_mode(mode)));
    Ok(())
}

pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
{
    _copy(from.as_ref(), to.as_ref())
}

fn _copy(from: &Path, to: &Path) -> io::Result<()> {
    if !from.is_file() {
        return Err(io::Error::new(io::ErrorKind::InvalidInput,
                              "the source path is not an existing regular file"))
    }

    let mut reader = try!(fs::File::open(from));
    let mut writer = try!(fs::File::create(to));
    let perm = try!(reader.metadata()).permissions();

    // Use buffer allocated on heap, because rust musl has very small stack
    // (80k) is is not enough for buffer + anything else
    let mut buf = vec![0; 65536];
    loop {
        let len = match reader.read(&mut buf) {
            Ok(0) => break,
            Ok(len) => len,
            Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
            Err(e) => return Err(e),
        };
        try!(writer.write_all(&buf[..len]));
    }

    try!(fs::set_permissions(to, perm));
    Ok(())
}

impl Lock {
    pub fn exclusive<P: AsRef<Path>>(p: P) -> Result<Lock, Error> {
        let f = try!(fs::File::create(p));
        try!(flock(f.as_raw_fd(), FlockArg::LockExclusiveNonblock)
            .map_err(|e| match e {
                nix::Error::Sys(code) => Error::from_raw_os_error(code as i32),
                nix::Error::InvalidPath => unreachable!(),
            }));
        Ok(Lock {
            file: f,
        })
    }
}

impl Drop for Lock {
    fn drop(&mut self) {
        flock(self.file.as_raw_fd(), FlockArg::Unlock)
            .map_err(|e| error!("Couldn't unlock file: {:?}", e)).ok();
    }
}
<commit_msg>Get copy() buffer back on stack (fixes #117)<commit_after>use std::io;
use std::io::{Read, Write, Error};
use std::path::{Path, PathBuf};
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::os::unix::io::AsRawFd;

use nix;
use nix::fcntl::{flock, FlockArg};

use path_util::PathExt;

pub struct Lock {
    file: fs::File,
}

pub fn read_visible_entries(dir: &Path) -> Result<Vec<PathBuf>, Error> {
    let mut res = vec!();
    for entry_ in try!(fs::read_dir(dir)) {
        let entry = try!(entry_);
        if !entry.file_name()[..].to_str().map(|x| x.starts_with("."))
            .unwrap_or(false)
        {
            res.push(entry.path().to_path_buf());
        }
    }
    Ok(res)
}

pub fn create_dir<P:AsRef<Path>>(path: P, recursive: bool) -> Result<(), Error>
{
    let path = path.as_ref();
    if path.is_dir() {
        return Ok(())
    }
    if recursive {
        match path.parent() {
            Some(p) if p != path => try!(create_dir(p, true)),
            _ => {}
        }
    }
    try!(fs::create_dir(path));
    try!(fs::set_permissions(path, fs::Permissions::from_mode(0o755)));
    Ok(())
}

pub fn create_dir_mode(path: &Path, mode: u32) -> Result<(), Error> {
    if path.is_dir() {
        return Ok(())
    }
    try!(fs::create_dir(path));
    try!(fs::set_permissions(path, fs::Permissions::from_mode(mode)));
    Ok(())
}

pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
{
    _copy(from.as_ref(), to.as_ref())
}

fn _copy(from: &Path, to: &Path) -> io::Result<()> {
    if !from.is_file() {
        return Err(io::Error::new(io::ErrorKind::InvalidInput,
                              "the source path is not an existing regular file"))
    }

    let mut reader = try!(fs::File::open(from));
    let mut writer = try!(fs::File::create(to));
    let perm = try!(reader.metadata()).permissions();

    // Use buffer allocated on heap, because rust musl has very small stack
    // (80k) is is not enough for buffer + anything else
    let mut buf = [0; 32768];
    loop {
        let len = match reader.read(&mut buf) {
            Ok(0) => break,
            Ok(len) => len,
            Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
            Err(e) => return Err(e),
        };
        try!(writer.write_all(&buf[..len]));
    }

    try!(fs::set_permissions(to, perm));
    Ok(())
}

impl Lock {
    pub fn exclusive<P: AsRef<Path>>(p: P) -> Result<Lock, Error> {
        let f = try!(fs::File::create(p));
        try!(flock(f.as_raw_fd(), FlockArg::LockExclusiveNonblock)
            .map_err(|e| match e {
                nix::Error::Sys(code) => Error::from_raw_os_error(code as i32),
                nix::Error::InvalidPath => unreachable!(),
            }));
        Ok(Lock {
            file: f,
        })
    }
}

impl Drop for Lock {
    fn drop(&mut self) {
        flock(self.file.as_raw_fd(), FlockArg::Unlock)
            .map_err(|e| error!("Couldn't unlock file: {:?}", e)).ok();
    }
}
<|endoftext|>