<commit_before>// CITA
// Copyright 2016-2019 Cryptape Technologies LLC.

// This program is free software: you can redistribute it
// and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any
// later version.

// This program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//! A multiplexed cita protocol

use byteorder::{ByteOrder, NetworkEndian};
use bytes::BufMut;
use bytes::BytesMut;
use logger::{error, warn};
use std::io;
use std::str;
use tokio::codec::{Decoder, Encoder};

pub type CitaRequest = (String, Vec<u8>);
pub type CitaResponse = Option<(String, Vec<u8>)>;

/// Our multiplexed line-based codec
pub struct CitaCodec;

/// Implementation of the multiplexed line-based protocol.
///
/// Frames begin with a 4 byte header, consisting of the numeric request ID
/// encoded in network order, followed by the frame payload encoded as a UTF-8
/// string and terminated with a '\n' character:
///
/// # An example frame:
///
/// +------------------------+--------------------------+
/// | Type                   | Content                  |
/// +------------------------+--------------------------+
/// | Symbol for Start       | \xDEADBEEF               |
/// | Length of Full Payload | u32                      |
/// +------------------------+--------------------------+
/// | Length of Key          | u8                       |
/// | Key                    | bytes of a str           |
/// +------------------------+--------------------------+
/// | Message                | a serialize data         |
/// +------------------------+--------------------------+
///

// Start of network messages.
const NETMSG_START: u64 = 0xDEAD_BEEF_0000_0000;

// According to CITA frame, defines its frame header length as:
// "Symbol for Start" + "Length of Full Payload" + "Length of Key",
// And this will consume "4 + 4 + 1" fixed-lengths of the frame.
pub const CITA_FRAME_HEADER_LEN: usize = 4 + 4 + 1;

fn opt_bytes_extend(buf: &mut BytesMut, data: &[u8]) {
    buf.reserve(data.len());
    unsafe {
        buf.bytes_mut()[..data.len()].copy_from_slice(data);
        buf.advance_mut(data.len());
    }
}

impl Decoder for CitaCodec {
    type Item = CitaRequest;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, io::Error> {
        Ok(network_message_to_pubsub_message(buf))
    }
}

impl Encoder for CitaCodec {
    type Item = CitaResponse;
    type Error = io::Error;

    fn encode(&mut self, msg: Self::Item, buf: &mut BytesMut) -> io::Result<()> {
        pubsub_message_to_network_message(buf, msg);
        Ok(())
    }
}

pub fn pubsub_message_to_network_message(buf: &mut BytesMut, msg: Option<(String, Vec<u8>)>) {
    let mut request_id_bytes = [0; 8];
    if let Some((key, body)) = msg {
        let length_key = key.len();
        // Use 1 byte to store key length.
        if length_key > u8::max_value() as usize {
            error!("[CitaProtocol] The MQ message key is too long {}.", key);
            return;
        }
        // Use 1 bytes to store the length for key, then store key, the last part is body.
        let length_full = 1 + length_key + body.len();
        if length_full > u32::max_value() as usize {
            error!(
                "[CitaProtocol] The MQ message with key {} is too long {}.",
                key,
                body.len()
            );
            return;
        }
        let request_id = NETMSG_START + length_full as u64;
        NetworkEndian::write_u64(&mut request_id_bytes, request_id);
        opt_bytes_extend(buf, &request_id_bytes);
        buf.put_u8(length_key as u8);
        opt_bytes_extend(buf, key.as_bytes());
        opt_bytes_extend(buf, &body);
    } else {
        let request_id = NETMSG_START;
        NetworkEndian::write_u64(&mut request_id_bytes, request_id);
        opt_bytes_extend(buf, &request_id_bytes);
    }
}

pub fn network_message_to_pubsub_message(buf: &mut BytesMut) -> Option<(String, Vec<u8>)> {
    if buf.len() < 8 {
        return None;
    }

    let request_id = NetworkEndian::read_u64(buf.as_ref());
    let netmsg_start = request_id & 0xffff_ffff_0000_0000;
    let length_full = (request_id & 0x0000_0000_ffff_ffff) as usize;
    if netmsg_start != NETMSG_START {
        return None;
    }
    if length_full + 8 > buf.len() {
        return None;
    }
    let _request_id_buf = buf.split_to(8);

    if length_full == 0 {
        return None;
    }
    let mut payload_buf = buf.split_to(length_full);

    let length_key = payload_buf[0] as usize;
    let _length_key_buf = payload_buf.split_to(1);
    if length_key == 0 {
        error!("[CitaProtocol] Network message key is empty.");
        return None;
    }
    if length_key > payload_buf.len() {
        error!(
            "[CitaProtocol] Buffer is not enough for key {} > {}.",
            length_key,
            buf.len()
        );
        return None;
    }
    let key_buf = payload_buf.split_to(length_key);
    let key_str_result = str::from_utf8(&key_buf);
    if key_str_result.is_err() {
        error!(
            "[CitaProtocol] Network message parse key error {:?}.",
            key_buf
        );
        return None;
    }
    let key = key_str_result.unwrap().to_string();
    if length_full == 1 + length_key {
        warn!("[CitaProtocol] Network message is empty.");
    }
    Some((key, payload_buf.to_vec()))
}

#[cfg(test)]
mod test {
    use super::{network_message_to_pubsub_message, pubsub_message_to_network_message};
    use bytes::BytesMut;

    #[test]
    fn convert_empty_message() {
        let mut buf = BytesMut::with_capacity(4 + 4);
        pubsub_message_to_network_message(&mut buf, None);
        let pub_msg_opt = network_message_to_pubsub_message(&mut buf);
        assert!(pub_msg_opt.is_none());
    }

    #[test]
    fn convert_messages() {
        let key = "this-is-the-key".to_string();
        let msg: Vec<u8> = vec![1, 3, 5, 7, 9];
        let mut buf = BytesMut::with_capacity(4 + 4 + 1 + key.len() + msg.len());
        pubsub_message_to_network_message(&mut buf, Some((key.clone(), msg.clone())));
        let pub_msg_opt = network_message_to_pubsub_message(&mut buf);
        assert!(pub_msg_opt.is_some());
        let (key_new, msg_new) = pub_msg_opt.unwrap();
        assert_eq!(key, key_new);
        assert_eq!(msg, msg_new);
    }
}
<commit_msg>delete useless code<commit_after>// CITA
// Copyright 2016-2019 Cryptape Technologies LLC.

// This program is free software: you can redistribute it
// and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any
// later version.

// This program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//! A multiplexed cita protocol

use byteorder::{ByteOrder, NetworkEndian};
use bytes::BufMut;
use bytes::BytesMut;
use logger::{error, warn};
use std::str;

/// Implementation of the multiplexed line-based protocol.
///
/// Frames begin with a 4 byte header, consisting of the numeric request ID
/// encoded in network order, followed by the frame payload encoded as a UTF-8
/// string and terminated with a '\n' character:
///
/// # An example frame:
///
/// +------------------------+--------------------------+
/// | Type                   | Content                  |
/// +------------------------+--------------------------+
/// | Symbol for Start       | \xDEADBEEF               |
/// | Length of Full Payload | u32                      |
/// +------------------------+--------------------------+
/// | Length of Key          | u8                       |
/// | Key                    | bytes of a str           |
/// +------------------------+--------------------------+
/// | Message                | a serialize data         |
/// +------------------------+--------------------------+
///

// Start of network messages.
const NETMSG_START: u64 = 0xDEAD_BEEF_0000_0000;

// According to CITA frame, defines its frame header length as:
// "Symbol for Start" + "Length of Full Payload" + "Length of Key",
// And this will consume "4 + 4 + 1" fixed-lengths of the frame.
pub const CITA_FRAME_HEADER_LEN: usize = 4 + 4 + 1;

fn opt_bytes_extend(buf: &mut BytesMut, data: &[u8]) {
    buf.reserve(data.len());
    unsafe {
        buf.bytes_mut()[..data.len()].copy_from_slice(data);
        buf.advance_mut(data.len());
    }
}

pub fn pubsub_message_to_network_message(buf: &mut BytesMut, msg: Option<(String, Vec<u8>)>) {
    let mut request_id_bytes = [0; 8];
    if let Some((key, body)) = msg {
        let length_key = key.len();
        // Use 1 byte to store key length.
        if length_key > u8::max_value() as usize {
            error!("[CitaProtocol] The MQ message key is too long {}.", key);
            return;
        }
        // Use 1 bytes to store the length for key, then store key, the last part is body.
        let length_full = 1 + length_key + body.len();
        if length_full > u32::max_value() as usize {
            error!(
                "[CitaProtocol] The MQ message with key {} is too long {}.",
                key,
                body.len()
            );
            return;
        }
        let request_id = NETMSG_START + length_full as u64;
        NetworkEndian::write_u64(&mut request_id_bytes, request_id);
        opt_bytes_extend(buf, &request_id_bytes);
        buf.put_u8(length_key as u8);
        opt_bytes_extend(buf, key.as_bytes());
        opt_bytes_extend(buf, &body);
    } else {
        let request_id = NETMSG_START;
        NetworkEndian::write_u64(&mut request_id_bytes, request_id);
        opt_bytes_extend(buf, &request_id_bytes);
    }
}

pub fn network_message_to_pubsub_message(buf: &mut BytesMut) -> Option<(String, Vec<u8>)> {
    if buf.len() < 8 {
        return None;
    }

    let request_id = NetworkEndian::read_u64(buf.as_ref());
    let netmsg_start = request_id & 0xffff_ffff_0000_0000;
    let length_full = (request_id & 0x0000_0000_ffff_ffff) as usize;
    if netmsg_start != NETMSG_START {
        return None;
    }
    if length_full + 8 > buf.len() {
        return None;
    }
    let _request_id_buf = buf.split_to(8);

    if length_full == 0 {
        return None;
    }
    let mut payload_buf = buf.split_to(length_full);

    let length_key = payload_buf[0] as usize;
    let _length_key_buf = payload_buf.split_to(1);
    if length_key == 0 {
        error!("[CitaProtocol] Network message key is empty.");
        return None;
    }
    if length_key > payload_buf.len() {
        error!(
            "[CitaProtocol] Buffer is not enough for key {} > {}.",
            length_key,
            buf.len()
        );
        return None;
    }
    let key_buf = payload_buf.split_to(length_key);
    let key_str_result = str::from_utf8(&key_buf);
    if key_str_result.is_err() {
        error!(
            "[CitaProtocol] Network message parse key error {:?}.",
            key_buf
        );
        return None;
    }
    let key = key_str_result.unwrap().to_string();
    if length_full == 1 + length_key {
        warn!("[CitaProtocol] Network message is empty.");
    }
    Some((key, payload_buf.to_vec()))
}

#[cfg(test)]
mod test {
    use super::{network_message_to_pubsub_message, pubsub_message_to_network_message};
    use bytes::BytesMut;

    #[test]
    fn convert_empty_message() {
        let mut buf = BytesMut::with_capacity(4 + 4);
        pubsub_message_to_network_message(&mut buf, None);
        let pub_msg_opt = network_message_to_pubsub_message(&mut buf);
        assert!(pub_msg_opt.is_none());
    }

    #[test]
    fn convert_messages() {
        let key = "this-is-the-key".to_string();
        let msg: Vec<u8> = vec![1, 3, 5, 7, 9];
        let mut buf = BytesMut::with_capacity(4 + 4 + 1 + key.len() + msg.len());
        pubsub_message_to_network_message(&mut buf, Some((key.clone(), msg.clone())));
        let pub_msg_opt = network_message_to_pubsub_message(&mut buf);
        assert!(pub_msg_opt.is_some());
        let (key_new, msg_new) = pub_msg_opt.unwrap();
        assert_eq!(key, key_new);
        assert_eq!(msg, msg_new);
    }
}
<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::error::Error;
use std::io::Write;
use std::io::stderr;

use ansi_term::Colour::Red;

/// Print an Error type and its cause recursively
///
/// The error is printed with "Error NNNN :" as prefix, where "NNNN" is a number which increases
/// which each recursion into the errors cause. The error description is used to visualize what
/// failed and if there is a cause "-- caused by:" is appended, and the cause is printed on the next
/// line.
///
/// Example output:
///
/// ```ignore
/// Error    1 : Some error -- caused by:
/// Error    2 : Some other error -- caused by:
/// Error    3 : Yet another Error -- caused by:
/// ...
///
/// Error <NNNN> : <Error description>
/// ```
pub fn trace_error(e: &Error) {
    print_trace_maxdepth(count_error_causes(e), e, ::std::u64::MAX);
    write!(stderr(), "\n").ok();
}

/// Convenience function: calls `trace_error()` with `e` and afterwards `std::process::exit()`
/// with `code`
pub fn trace_error_exit(e: &Error, code: i32) -> ! {
    use std::process::exit;

    debug!("Tracing error...");
    trace_error(e);
    debug!("Calling exit()");
    exit(code);
}

/// Print an Error type and its cause recursively, but only `max` levels
///
/// Output is the same as for `trace_error()`, though there are only `max` levels printed.
pub fn trace_error_maxdepth(e: &Error, max: u64) {
    let n = count_error_causes(e);
    let msg = Red.blink().paint(format!("{}/{} Levels of errors will be printed\n",
                                        (if max > n { n } else { max }), n));
    write!(stderr(), "{}", msg).ok();
    print_trace_maxdepth(n, e, max);
    write!(stderr(), "").ok();
}

/// Print an Error type and its cause recursively with the debug!() macro
///
/// Output is the same as for `trace_error()`.
pub fn trace_error_dbg(e: &Error) {
    print_trace_dbg(0, e);
}

/// Helper function for `trace_error()` and `trace_error_maxdepth()`.
///
/// Returns the cause of the last processed error in the recursion, so `None` if all errors where
/// processed.
fn print_trace_maxdepth(idx: u64, e: &Error, max: u64) -> Option<&Error> {
    if e.cause().is_some() && idx > 0 {
        e.cause().map(|cause| {
            match print_trace_maxdepth(idx - 1, cause, max) {
                None    => write!(stderr(), "\n").ok(),
                Some(_) => write!(stderr(), " -- caused:\n").ok(),
            };
        });
    } else {
        write!(stderr(), "\n").ok();
    }
    write!(stderr(), "{}: {}", Red.paint(format!("ERROR[{:>4}]", idx)), e.description()).ok();
    e.cause()
}

/// Count errors in `Error::cause()` recursively
fn count_error_causes(e: &Error) -> u64 {
    1 + e.cause().map(|c| count_error_causes(c)).unwrap_or(0)
}

fn print_trace_dbg(idx: u64, e: &Error) {
    debug!("{}: {}", Red.blink().paint(format!("ERROR[{:>4}]", idx)), e.description());
    if e.cause().is_some() {
        e.cause().map(|c| print_trace_dbg(idx + 1, c));
    }
}

/// Helper functions for `Result<T, E>` types to reduce overhead in the following situations:
///
/// ```ignore
/// function().map_err(|e| { trace_error(&e); e })
/// ```
///
/// and variants
pub trait MapErrTrace {
    fn map_err_trace(self) -> Self;
    fn map_err_dbg_trace(self) -> Self;
    fn map_err_trace_exit(self, code: i32) -> Self;
    fn map_err_trace_maxdepth(self, max: u64) -> Self;
}

impl<U, E: Error> MapErrTrace for Result<U, E> {

    /// Simply call `trace_error()` on the Err (if there is one) and return the error.
    ///
    /// This does nothing besides the side effect of printing the error trace
    fn map_err_trace(self) -> Self {
        self.map_err(|e| { trace_error(&e); e })
    }

    /// Simply call `trace_error_dbg()` on the Err (if there is one) and return the error.
    ///
    /// This does nothing besides the side effect of printing the error trace
    fn map_err_dbg_trace(self) -> Self {
        self.map_err(|e| { trace_error_dbg(&e); e })
    }

    /// Simply call `trace_error_exit(code)` on the Err (if there is one).
    ///
    /// This does not return if there is an Err(e).
    fn map_err_trace_exit(self, code: i32) -> Self {
        self.map_err(|e| { trace_error_exit(&e, code) })
    }

    /// Simply call `trace_error_maxdepth(max)` on the Err (if there is one) and return the error.
    ///
    /// This does nothing besides the side effect of printing the error trace to a certain depth
    fn map_err_trace_maxdepth(self, max: u64) -> Self {
        self.map_err(|e| { trace_error_maxdepth(&e, max); e })
    }

}

<commit_msg>Add helper for tracing error and exit or unwrap the value<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::error::Error;
use std::io::Write;
use std::io::stderr;

use ansi_term::Colour::Red;

/// Print an Error type and its cause recursively
///
/// The error is printed with "Error NNNN :" as prefix, where "NNNN" is a number which increases
/// which each recursion into the errors cause. The error description is used to visualize what
/// failed and if there is a cause "-- caused by:" is appended, and the cause is printed on the next
/// line.
///
/// Example output:
///
/// ```ignore
/// Error    1 : Some error -- caused by:
/// Error    2 : Some other error -- caused by:
/// Error    3 : Yet another Error -- caused by:
/// ...
///
/// Error <NNNN> : <Error description>
/// ```
pub fn trace_error(e: &Error) {
    print_trace_maxdepth(count_error_causes(e), e, ::std::u64::MAX);
    write!(stderr(), "\n").ok();
}

/// Convenience function: calls `trace_error()` with `e` and afterwards `std::process::exit()`
/// with `code`
pub fn trace_error_exit(e: &Error, code: i32) -> ! {
    use std::process::exit;

    debug!("Tracing error...");
    trace_error(e);
    debug!("Calling exit()");
    exit(code);
}

/// Print an Error type and its cause recursively, but only `max` levels
///
/// Output is the same as for `trace_error()`, though there are only `max` levels printed.
pub fn trace_error_maxdepth(e: &Error, max: u64) {
    let n = count_error_causes(e);
    let msg = Red.blink().paint(format!("{}/{} Levels of errors will be printed\n",
                                        (if max > n { n } else { max }), n));
    write!(stderr(), "{}", msg).ok();
    print_trace_maxdepth(n, e, max);
    write!(stderr(), "").ok();
}

/// Print an Error type and its cause recursively with the debug!() macro
///
/// Output is the same as for `trace_error()`.
pub fn trace_error_dbg(e: &Error) {
    print_trace_dbg(0, e);
}

/// Helper function for `trace_error()` and `trace_error_maxdepth()`.
///
/// Returns the cause of the last processed error in the recursion, so `None` if all errors where
/// processed.
fn print_trace_maxdepth(idx: u64, e: &Error, max: u64) -> Option<&Error> {
    if e.cause().is_some() && idx > 0 {
        e.cause().map(|cause| {
            match print_trace_maxdepth(idx - 1, cause, max) {
                None    => write!(stderr(), "\n").ok(),
                Some(_) => write!(stderr(), " -- caused:\n").ok(),
            };
        });
    } else {
        write!(stderr(), "\n").ok();
    }
    write!(stderr(), "{}: {}", Red.paint(format!("ERROR[{:>4}]", idx)), e.description()).ok();
    e.cause()
}

/// Count errors in `Error::cause()` recursively
fn count_error_causes(e: &Error) -> u64 {
    1 + e.cause().map(|c| count_error_causes(c)).unwrap_or(0)
}

fn print_trace_dbg(idx: u64, e: &Error) {
    debug!("{}: {}", Red.blink().paint(format!("ERROR[{:>4}]", idx)), e.description());
    if e.cause().is_some() {
        e.cause().map(|c| print_trace_dbg(idx + 1, c));
    }
}

/// Helper functions for `Result<T, E>` types to reduce overhead in the following situations:
///
/// ```ignore
/// function().map_err(|e| { trace_error(&e); e })
/// ```
///
/// and variants
pub trait MapErrTrace {
    type Output;

    fn map_err_trace(self) -> Self;
    fn map_err_dbg_trace(self) -> Self;
    fn map_err_trace_exit(self, code: i32) -> Self;
    fn map_err_trace_exit_unwrap(self, code: i32) -> Self::Output;
    fn map_err_trace_maxdepth(self, max: u64) -> Self;
}

impl<U, E: Error> MapErrTrace for Result<U, E> {
    type Output = U;

    /// Simply call `trace_error()` on the Err (if there is one) and return the error.
    ///
    /// This does nothing besides the side effect of printing the error trace
    fn map_err_trace(self) -> Self {
        self.map_err(|e| { trace_error(&e); e })
    }

    /// Simply call `trace_error_dbg()` on the Err (if there is one) and return the error.
    ///
    /// This does nothing besides the side effect of printing the error trace
    fn map_err_dbg_trace(self) -> Self {
        self.map_err(|e| { trace_error_dbg(&e); e })
    }

    /// Simply call `trace_error_exit(code)` on the Err (if there is one).
    ///
    /// This does not return if there is an Err(e).
    fn map_err_trace_exit(self, code: i32) -> Self {
        self.map_err(|e| { trace_error_exit(&e, code) })
    }

    /// Helper for calling map_err_trace_exit(n).unwrap() in one call
    fn map_err_trace_exit_unwrap(self, code: i32) -> Self::Output {
        self.map_err_trace_exit(code).unwrap()
    }

    /// Simply call `trace_error_maxdepth(max)` on the Err (if there is one) and return the error.
    ///
    /// This does nothing besides the side effect of printing the error trace to a certain depth
    fn map_err_trace_maxdepth(self, max: u64) -> Self {
        self.map_err(|e| { trace_error_maxdepth(&e, max); e })
    }

}

<|endoftext|>


<commit_before>extern crate curl;
extern crate flate2;
extern crate pkg_config;
extern crate semver;
extern crate tar;

use std::error::Error;
use std::fs::File;
use std::io::BufWriter;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process;
use std::process::Command;
use std::{env, fs};

use curl::easy::Easy;
use flate2::read::GzDecoder;
use semver::Version;
use tar::Archive;

const LIBRARY: &'static str = "tensorflow";
const REPOSITORY: &'static str = "https://github.com/tensorflow/tensorflow.git";
const TARGET: &'static str = "tensorflow:libtensorflow.so";
// `VERSION` and `TAG` are separate because the tag is not always `'v' + VERSION`.
const VERSION: &'static str = "1.0.0";
const TAG: &'static str = "v1.0.0";
const MIN_BAZEL: &'static str = "0.3.2";

macro_rules! get(($name:expr) => (ok!(env::var($name))));
macro_rules! ok(($expression:expr) => ($expression.unwrap()));
macro_rules! log {
    ($fmt:expr) => (println!(concat!("libtensorflow-sys/build.rs:{}: ", $fmt), line!()));
    ($fmt:expr, $($arg:tt)*) => (println!(concat!("libtensorflow-sys/build.rs:{}: ", $fmt),
    line!(), $($arg)*));
}
macro_rules! log_var(($var:ident) => (log!(concat!(stringify!($var), " = {:?}"), $var)));

fn main() {
    if pkg_config::find_library(LIBRARY).is_ok() {
        log!("Returning early because {} was already found", LIBRARY);
        return;
    }

    let force_src = match env::var("TF_RUST_BUILD_FROM_SRC") {
        Ok(s) => s == "true",
        Err(_) => false,
    };
    if !force_src && env::consts::ARCH == "x86_64" && (env::consts::OS == "linux" || env::consts::OS == "macos") {
        install_prebuilt();
    } else {
        build_from_src();
    }
}

fn remove_suffix(value: &mut String, suffix: &str) {
    if value.ends_with(suffix) {
        let n = value.len();
        value.truncate(n - suffix.len());
    }
}

fn extract<P: AsRef<Path>, P2: AsRef<Path>>(archive_path: P, extract_to: P2) {
    let file = File::open(archive_path).unwrap();
    let unzipped = GzDecoder::new(file).unwrap();
    let mut a = Archive::new(unzipped);
    a.unpack(extract_to).unwrap();
}

// Downloads and unpacks a prebuilt binary. Only works for certain platforms.
fn install_prebuilt() {
    // Figure out the file names.
    let os = match env::consts::OS {
        "macos" => "darwin",
        x => x,
    };
    let proc_type = if cfg!(feature = "tensorflow_gpu") {"gpu"} else {"cpu"};
    let binary_url = format!(
        "https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-{}-{}-{}-{}.tar.gz",
        proc_type, os, env::consts::ARCH, VERSION);
    log_var!(binary_url);
    let short_file_name = binary_url.split("/").last().unwrap();
    let mut base_name = short_file_name.to_string();
    remove_suffix(&mut base_name, ".tar.gz");
    log_var!(base_name);
    let download_dir = match env::var("TF_RUST_DOWNLOAD_DIR") {
        Ok(s) => PathBuf::from(s),
        Err(_) => PathBuf::from(&get!("CARGO_MANIFEST_DIR")).join("target"),
    };
    if !download_dir.exists() {
        fs::create_dir(&download_dir).unwrap();
    }
    let file_name = download_dir.join(short_file_name);
    log_var!(file_name);

    // Download the tarball.
    if !file_name.exists() {
        let f = File::create(&file_name).unwrap();
        let mut writer = BufWriter::new(f);
        let mut easy = Easy::new();
        easy.url(&binary_url).unwrap();
        easy.write_function(move |data| {
            Ok(writer.write(data).unwrap())
        }).unwrap();
        easy.perform().unwrap();

        let response_code = easy.response_code().unwrap();
        if response_code != 200 {
            panic!("Unexpected response code {} for {}", response_code, binary_url);
        }
    }

    // Extract the tarball.
    let unpacked_dir = download_dir.join(base_name);
    let lib_dir = unpacked_dir.join("lib");
    if !lib_dir.join(format!("lib{}.so", LIBRARY)).exists() {
        extract(file_name, &unpacked_dir);
    }

    //run("find", |command| command); // TODO: remove
    run("ls", |command| {
        command.arg("-l").arg(lib_dir.to_str().unwrap())
        }); // TODO: remove

    println!("cargo:rustc-link-lib=dylib={}", LIBRARY);
    println!("cargo:rustc-link-search={}", lib_dir.display());
}

fn build_from_src() {
    let output = PathBuf::from(&get!("OUT_DIR"));
    log_var!(output);
    let source = PathBuf::from(&get!("CARGO_MANIFEST_DIR")).join(format!("target/source-{}", TAG));
    log_var!(source);
    let lib_dir = output.join(format!("lib-{}", TAG));
    log_var!(lib_dir);
    if lib_dir.exists() {
        log!("Directory {:?} already exists", lib_dir);
    } else {
        log!("Creating directory {:?}", lib_dir);
        fs::create_dir(lib_dir.clone()).unwrap();
    }
    let library_path = lib_dir.join(format!("lib{}.so", LIBRARY));
    log_var!(library_path);
    if library_path.exists() {
        log!("{:?} already exists, not building", library_path);
    } else {
        if let Err(e) = check_bazel() {
            println!("cargo:error=Bazel must be installed at version {} or greater. (Error: {})",
                     MIN_BAZEL,
                     e);
            process::exit(1);
        }
        let target_path = &TARGET.replace(":", "/");
        log_var!(target_path);
        if !Path::new(&source.join(".git")).exists() {
            run("git", |command| {
                command.arg("clone")
                    .arg(format!("--branch={}", TAG))
                    .arg("--recursive")
                    .arg(REPOSITORY)
                    .arg(&source)
            });
        }
        // Only configure if not previously configured.  Configuring runs a
        // `bazel clean`, which we don't want, because we want to be able to
        // continue from a cancelled build.
        let configure_hint_file_pb = source.join(".rust-configured");
        let configure_hint_file = Path::new(&configure_hint_file_pb);
        if !configure_hint_file.exists() {
            run("bash",
                |command| command.current_dir(&source)
                .env("TF_NEED_CUDA", if cfg!(feature = "tensorflow_gpu") {"1"} else {"0"})
                .arg("-c")
                .arg("yes ''|./configure"));
            File::create(configure_hint_file).unwrap();
        }
        run("bazel", |command| {
            command.current_dir(&source)
                .arg("build")
                .arg(format!("--jobs={}", get!("NUM_JOBS")))
                .arg("--compilation_mode=opt")
                .arg("--copt=-march=native")
                .arg(TARGET)
        });
        let target_bazel_bin = source.join("bazel-bin").join(target_path);
        log!("Copying {:?} to {:?}", target_bazel_bin, library_path);
        fs::copy(target_bazel_bin, library_path).unwrap();
    }

    println!("cargo:rustc-link-lib=dylib={}", LIBRARY);
    println!("cargo:rustc-link-search={}", lib_dir.display());
}

fn run<F>(name: &str, mut configure: F)
    where F: FnMut(&mut Command) -> &mut Command
{
    let mut command = Command::new(name);
    let configured = configure(&mut command);
    log!("Executing {:?}", configured);
    if !ok!(configured.status()).success() {
        panic!("failed to execute {:?}", configured);
    }
    log!("Command {:?} finished successfully", configured);
}

// Building TF 0.11.0rc1 with Bazel 0.3.0 gives this error when running `configure`:
//   expected ConfigurationTransition or NoneType for 'cfg' while calling label_list but got
// string instead:     data.
//       ERROR: com.google.devtools.build.lib.packages.BuildFileContainsErrorsException: error
// loading package '': Extension file 'tensorflow/tensorflow.bzl' has errors.
// And the simple solution is to require Bazel 0.3.1 or higher.
fn check_bazel() -> Result<(), Box<Error>> {
    let mut command = Command::new("bazel");
    command.arg("version");
    log!("Executing {:?}", command);
    let out = try!(command.output());
    log!("Command {:?} finished successfully", command);
    let stdout = try!(String::from_utf8(out.stdout));
    let mut found_version = false;
    for line in stdout.lines() {
        if line.starts_with("Build label:") {
            found_version = true;
            let mut version_str = line.split(":")
                .nth(1)
                .unwrap()
                .split(" ")
                .nth(1)
                .unwrap()
                .trim();
            if version_str.ends_with('-') {
                // hyphen is 1 byte long, so it's safe
                version_str = &version_str[..version_str.len() - 1];
            }
            let version = try!(Version::parse(version_str));
            let want = try!(Version::parse(MIN_BAZEL));
            if version < want {
                return Err(format!("Installed version {} is less than required version {}",
                                   version_str,
                                   MIN_BAZEL)
                    .into());
            }
        }
    }
    if !found_version {
        return Err("Did not find version number in `bazel version` output.".into());
    }
    Ok(())
}
<commit_msg>Fix running under nightly: copy prebuilt `libtensorflow.so` to `OUT_DIR`<commit_after>extern crate curl;
extern crate flate2;
extern crate pkg_config;
extern crate semver;
extern crate tar;

use std::error::Error;
use std::fs::File;
use std::io::BufWriter;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process;
use std::process::Command;
use std::{env, fs};

use curl::easy::Easy;
use flate2::read::GzDecoder;
use semver::Version;
use tar::Archive;

const LIBRARY: &'static str = "tensorflow";
const REPOSITORY: &'static str = "https://github.com/tensorflow/tensorflow.git";
const TARGET: &'static str = "tensorflow:libtensorflow.so";
// `VERSION` and `TAG` are separate because the tag is not always `'v' + VERSION`.
const VERSION: &'static str = "1.0.0";
const TAG: &'static str = "v1.0.0";
const MIN_BAZEL: &'static str = "0.3.2";

macro_rules! get(($name:expr) => (ok!(env::var($name))));
macro_rules! ok(($expression:expr) => ($expression.unwrap()));
macro_rules! log {
    ($fmt:expr) => (println!(concat!("libtensorflow-sys/build.rs:{}: ", $fmt), line!()));
    ($fmt:expr, $($arg:tt)*) => (println!(concat!("libtensorflow-sys/build.rs:{}: ", $fmt),
    line!(), $($arg)*));
}
macro_rules! log_var(($var:ident) => (log!(concat!(stringify!($var), " = {:?}"), $var)));

fn main() {
    if pkg_config::find_library(LIBRARY).is_ok() {
        log!("Returning early because {} was already found", LIBRARY);
        return;
    }

    let force_src = match env::var("TF_RUST_BUILD_FROM_SRC") {
        Ok(s) => s == "true",
        Err(_) => false,
    };
    if !force_src && env::consts::ARCH == "x86_64" && (env::consts::OS == "linux" || env::consts::OS == "macos") {
        install_prebuilt();
    } else {
        build_from_src();
    }
}

fn remove_suffix(value: &mut String, suffix: &str) {
    if value.ends_with(suffix) {
        let n = value.len();
        value.truncate(n - suffix.len());
    }
}

fn extract<P: AsRef<Path>, P2: AsRef<Path>>(archive_path: P, extract_to: P2) {
    let file = File::open(archive_path).unwrap();
    let unzipped = GzDecoder::new(file).unwrap();
    let mut a = Archive::new(unzipped);
    a.unpack(extract_to).unwrap();
}

// Downloads and unpacks a prebuilt binary. Only works for certain platforms.
fn install_prebuilt() {
    // Figure out the file names.
    let os = match env::consts::OS {
        "macos" => "darwin",
        x => x,
    };
    let proc_type = if cfg!(feature = "tensorflow_gpu") {"gpu"} else {"cpu"};
    let binary_url = format!(
        "https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-{}-{}-{}-{}.tar.gz",
        proc_type, os, env::consts::ARCH, VERSION);
    log_var!(binary_url);
    let short_file_name = binary_url.split("/").last().unwrap();
    let mut base_name = short_file_name.to_string();
    remove_suffix(&mut base_name, ".tar.gz");
    log_var!(base_name);
    let download_dir = match env::var("TF_RUST_DOWNLOAD_DIR") {
        Ok(s) => PathBuf::from(s),
        Err(_) => PathBuf::from(&get!("CARGO_MANIFEST_DIR")).join("target"),
    };
    if !download_dir.exists() {
        fs::create_dir(&download_dir).unwrap();
    }
    let file_name = download_dir.join(short_file_name);
    log_var!(file_name);

    // Download the tarball.
    if !file_name.exists() {
        let f = File::create(&file_name).unwrap();
        let mut writer = BufWriter::new(f);
        let mut easy = Easy::new();
        easy.url(&binary_url).unwrap();
        easy.write_function(move |data| {
            Ok(writer.write(data).unwrap())
        }).unwrap();
        easy.perform().unwrap();

        let response_code = easy.response_code().unwrap();
        if response_code != 200 {
            panic!("Unexpected response code {} for {}", response_code, binary_url);
        }
    }

    // Extract the tarball.
    let unpacked_dir = download_dir.join(base_name);
    let lib_dir = unpacked_dir.join("lib");
    let library_file = format!("lib{}.so", LIBRARY);
    let library_full_path = lib_dir.join(&library_file);
    if !library_full_path.exists() {
        extract(file_name, &unpacked_dir);
    }

    //run("find", |command| command); // TODO: remove
    run("ls", |command| {
        command.arg("-l").arg(lib_dir.to_str().unwrap())
        }); // TODO: remove

    println!("cargo:rustc-link-lib=dylib={}", LIBRARY);
    let output = PathBuf::from(&get!("OUT_DIR"));
    let new_library_full_path = output.join(&library_file);
    if new_library_full_path.exists() {
        println!("File {} already exists, deleting.", new_library_full_path.display());
        std::fs::remove_file(&new_library_full_path).unwrap();
    }

    println!("Copying {} to {}...", library_full_path.display(), new_library_full_path.display());
    std::fs::copy(&library_full_path, &new_library_full_path).unwrap();
    println!("cargo:rustc-link-search={}", output.display());
}

fn build_from_src() {
    let output = PathBuf::from(&get!("OUT_DIR"));
    log_var!(output);
    let source = PathBuf::from(&get!("CARGO_MANIFEST_DIR")).join(format!("target/source-{}", TAG));
    log_var!(source);
    let lib_dir = output.join(format!("lib-{}", TAG));
    log_var!(lib_dir);
    if lib_dir.exists() {
        log!("Directory {:?} already exists", lib_dir);
    } else {
        log!("Creating directory {:?}", lib_dir);
        fs::create_dir(lib_dir.clone()).unwrap();
    }
    let library_path = lib_dir.join(format!("lib{}.so", LIBRARY));
    log_var!(library_path);
    if library_path.exists() {
        log!("{:?} already exists, not building", library_path);
    } else {
        if let Err(e) = check_bazel() {
            println!("cargo:error=Bazel must be installed at version {} or greater. (Error: {})",
                     MIN_BAZEL,
                     e);
            process::exit(1);
        }
        let target_path = &TARGET.replace(":", "/");
        log_var!(target_path);
        if !Path::new(&source.join(".git")).exists() {
            run("git", |command| {
                command.arg("clone")
                    .arg(format!("--branch={}", TAG))
                    .arg("--recursive")
                    .arg(REPOSITORY)
                    .arg(&source)
            });
        }
        // Only configure if not previously configured.  Configuring runs a
        // `bazel clean`, which we don't want, because we want to be able to
        // continue from a cancelled build.
        let configure_hint_file_pb = source.join(".rust-configured");
        let configure_hint_file = Path::new(&configure_hint_file_pb);
        if !configure_hint_file.exists() {
            run("bash",
                |command| command.current_dir(&source)
                .env("TF_NEED_CUDA", if cfg!(feature = "tensorflow_gpu") {"1"} else {"0"})
                .arg("-c")
                .arg("yes ''|./configure"));
            File::create(configure_hint_file).unwrap();
        }
        run("bazel", |command| {
            command.current_dir(&source)
                .arg("build")
                .arg(format!("--jobs={}", get!("NUM_JOBS")))
                .arg("--compilation_mode=opt")
                .arg("--copt=-march=native")
                .arg(TARGET)
        });
        let target_bazel_bin = source.join("bazel-bin").join(target_path);
        log!("Copying {:?} to {:?}", target_bazel_bin, library_path);
        fs::copy(target_bazel_bin, library_path).unwrap();
    }

    println!("cargo:rustc-link-lib=dylib={}", LIBRARY);
    println!("cargo:rustc-link-search={}", lib_dir.display());
}

fn run<F>(name: &str, mut configure: F)
    where F: FnMut(&mut Command) -> &mut Command
{
    let mut command = Command::new(name);
    let configured = configure(&mut command);
    log!("Executing {:?}", configured);
    if !ok!(configured.status()).success() {
        panic!("failed to execute {:?}", configured);
    }
    log!("Command {:?} finished successfully", configured);
}

// Building TF 0.11.0rc1 with Bazel 0.3.0 gives this error when running `configure`:
//   expected ConfigurationTransition or NoneType for 'cfg' while calling label_list but got
// string instead:     data.
//       ERROR: com.google.devtools.build.lib.packages.BuildFileContainsErrorsException: error
// loading package '': Extension file 'tensorflow/tensorflow.bzl' has errors.
// And the simple solution is to require Bazel 0.3.1 or higher.
fn check_bazel() -> Result<(), Box<Error>> {
    let mut command = Command::new("bazel");
    command.arg("version");
    log!("Executing {:?}", command);
    let out = try!(command.output());
    log!("Command {:?} finished successfully", command);
    let stdout = try!(String::from_utf8(out.stdout));
    let mut found_version = false;
    for line in stdout.lines() {
        if line.starts_with("Build label:") {
            found_version = true;
            let mut version_str = line.split(":")
                .nth(1)
                .unwrap()
                .split(" ")
                .nth(1)
                .unwrap()
                .trim();
            if version_str.ends_with('-') {
                // hyphen is 1 byte long, so it's safe
                version_str = &version_str[..version_str.len() - 1];
            }
            let version = try!(Version::parse(version_str));
            let want = try!(Version::parse(MIN_BAZEL));
            if version < want {
                return Err(format!("Installed version {} is less than required version {}",
                                   version_str,
                                   MIN_BAZEL)
                    .into());
            }
        }
    }
    if !found_version {
        return Err("Did not find version number in `bazel version` output.".into());
    }
    Ok(())
}
<|endoftext|>


<commit_before>#![cfg(feature = "pricing")]

extern crate rusoto_core;
extern crate rusoto_pricing;

use rusoto_core::Region;
use rusoto_pricing::{PricingClient, Pricing, DescribeServicesRequest};

#[test]
fn should_list_hits() {
    let client = PricingClient::new(Region::UsEast1);
    let request = DescribeServicesRequest::default();

    match client.describe_services(request).sync() {
        Err(e) => panic!("Couldn't describe services: {}", e),
        Ok(result) => println!("Services: {:?}", result),
    }
}<commit_msg>Fix pricing api test name.<commit_after>#![cfg(feature = "pricing")]

extern crate rusoto_core;
extern crate rusoto_pricing;

use rusoto_core::Region;
use rusoto_pricing::{PricingClient, Pricing, DescribeServicesRequest};

#[test]
fn should_describe_services() {
    let client = PricingClient::new(Region::UsEast1);
    let request = DescribeServicesRequest::default();

    match client.describe_services(request).sync() {
        Err(e) => panic!("Couldn't describe services: {}", e),
        Ok(result) => println!("Services: {:?}", result),
    }
}<|endoftext|>


<commit_before>extern crate basic_dsp;
extern crate docopt;
extern crate time;
extern crate rand;

use basic_dsp::*;
use std::env;
use time::PreciseTime;
use docopt::Docopt;
use rand::*;
use std::collections::HashMap;
const INIT_VAL_RANGE: (f32, f32) = (-100.0, 100.0);

const USAGE: &'static str = "
Benchmarks various functions over different daza sizes and prints the results to STDOUT in
a table format. Results can be piped to `plot_csv_data.py` to produce a plot.

Usage: bench_tables [--limit=<size>]
       bench_tables (--help)

Options:
    -h, --help  Display usage.
	--limit=<size>     Data sizes tested will not exceed this value. [default: 0]
";

fn main() {
    let argv = env::args();
    let args = Docopt::new(USAGE)
                  .and_then(|d| d.argv(argv.into_iter()).parse())
                  .unwrap_or_else(|e| e.exit());
    if args.get_bool("-h") || args.get_bool("--help") {
        println!("{}", USAGE);
        std::process::exit(0);
    }

	let limit_arg = args.get_str("--limit");
	let limit = if limit_arg != "" {
		match limit_arg.trim().parse::<usize>().ok() {
			 Some(l) => l,
			 _ => {
				 println!("{}", USAGE);
	         	  std::process::exit(1);}
		}
	} else {
		0
	};

	let mut results: HashMap<&'static str, Vec<i64>, _> = HashMap::new();
	results.insert("Offset", Vec::new());
	results.insert("Sin", Vec::new());
	results.insert("Log", Vec::new());
	results.insert("Powf", Vec::new());
	results.insert("Sqrt", Vec::new());

	let data_sizes: Vec<usize> = vec![1000, 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000,
					  100000, 200000, 500000, 1000000, 10000000, 500000, 100000000];
	let data_sizes: Vec<usize> =
		data_sizes.into_iter()
		.take_while(|x| limit == 0 || *x <= limit)
		.collect();
    for data_set_size in &data_sizes {
		//let mut buffer = SingleBuffer::new();
		let original = {
	        let mut vec = vec![0.0; *data_set_size];
	        let seed: &[_] = &[5798734, 198196];
	        let mut rng: StdRng = SeedableRng::from_seed(seed); // Create repeatable data
	        for n in &mut vec {
	            *n = rng.gen_range(INIT_VAL_RANGE.0, INIT_VAL_RANGE.1);
	        }
	        vec
	    };
		let mut dsp = original.clone().to_real_time_vec();
		let start = PreciseTime::now();
		dsp.offset(5.0);
		let end = PreciseTime::now();
		let duration = start.to(end).num_nanoseconds().unwrap();
		results.get_mut("Offset").unwrap().push(duration);

		let mut dsp = original.clone().to_real_time_vec();
		let start = PreciseTime::now();
		dsp.sin();
		let end = PreciseTime::now();
		let duration = start.to(end).num_nanoseconds().unwrap();
		results.get_mut("Sin").unwrap().push(duration);

		let mut dsp = original.clone().to_real_time_vec();
		let start = PreciseTime::now();
		dsp.log(10.0);
		let end = PreciseTime::now();
		let duration = start.to(end).num_nanoseconds().unwrap();
		results.get_mut("Log").unwrap().push(duration);

		let mut dsp = original.clone().to_real_time_vec();
		let start = PreciseTime::now();
		dsp.powf(5.0);
		let end = PreciseTime::now();
		let duration = start.to(end).num_nanoseconds().unwrap();
		results.get_mut("Powf").unwrap().push(duration);

		let mut dsp = original.clone().to_real_time_vec();
		let start = PreciseTime::now();
		dsp.sqrt();
		let end = PreciseTime::now();
		let duration = start.to(end).num_nanoseconds().unwrap();
		results.get_mut("Sqrt").unwrap().push(duration);
	}

	// Print
	print!("Sizes, ");
	for value in &data_sizes {
		print!("{:?}, ", value);
	}
	println!("");
	let mut sorted: Vec<_> = results.keys().map(|x|x.clone()).collect();
	sorted.sort();
	for key in &sorted {
		print!("{:?} [ns], ", key);
		for value in &results[key] {
			print!("{:?}, ", value);
		}
		println!("");
	}
}
<commit_msg>Removed code duplication<commit_after>extern crate basic_dsp;
extern crate docopt;
extern crate time;
extern crate rand;

use basic_dsp::*;
use std::env;
use time::PreciseTime;
use docopt::Docopt;
use rand::*;
use std::collections::HashMap;
const INIT_VAL_RANGE: (f64, f64) = (-100.0, 100.0);

const USAGE: &'static str = "
Benchmarks various functions over different daza sizes and prints the results to STDOUT in
a table format. Results can be piped to `plot_csv_data.py` to produce a plot.

Usage: bench_tables [--limit=<size>]
       bench_tables (--help)

Options:
    -h, --help  Display usage.
	--limit=<size>     Data sizes tested will not exceed this value. [default: 0]
";

/// Benchmarks the given function. The results are more rough estimations and should
/// only be interpreted with care and in context of more results.
fn bench_real<F: FnMut(RealTimeVec64)>(
        name: &'static str,
        data: &Vec<f64>,
        results: &mut HashMap<&'static str, Vec<i64>>,
        mut func: F) {
    let dsp = data.clone().to_real_time_vec();
    let start = PreciseTime::now();
    func(dsp);
    let end = PreciseTime::now();
    let duration = start.to(end).num_nanoseconds().unwrap();
    results.entry(name).or_insert(Vec::new()).push(duration);
}

fn main() {
    let argv = env::args();
    let args = Docopt::new(USAGE)
                  .and_then(|d| d.argv(argv.into_iter()).parse())
                  .unwrap_or_else(|e| e.exit());
    if args.get_bool("-h") || args.get_bool("--help") {
        println!("{}", USAGE);
        std::process::exit(0);
    }

	let limit_arg = args.get_str("--limit");
	let limit = if limit_arg != "" {
		match limit_arg.trim().parse::<usize>().ok() {
			 Some(l) => l,
			 _ => {
				 println!("{}", USAGE);
	         	  std::process::exit(1);}
		}
	} else {
		0
	};

	let mut results: HashMap<&'static str, Vec<i64>, _> = HashMap::new();
	results.insert("Offset", Vec::new());
	results.insert("Sin", Vec::new());
	results.insert("Log", Vec::new());
	results.insert("Powf", Vec::new());
	results.insert("Sqrt", Vec::new());

	let data_sizes: Vec<usize> = vec![1000, 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000,
					  100000, 200000, 500000, 1000000, 10000000, 500000, 100000000];
	let data_sizes: Vec<usize> =
		data_sizes.into_iter()
		.take_while(|x| limit == 0 || *x <= limit)
		.collect();
    for data_set_size in &data_sizes {
		//let mut buffer = SingleBuffer::new();
		let original = {
	        let mut vec: Vec<f64> = vec![0.0; *data_set_size];
	        let seed: &[_] = &[5798734, 198196];
	        let mut rng: StdRng = SeedableRng::from_seed(seed); // Create repeatable data
	        for n in &mut vec {
	            *n = rng.gen_range(INIT_VAL_RANGE.0, INIT_VAL_RANGE.1);
	        }
	        vec
	    };
        bench_real("Offset", &original, &mut results, |mut v|v.offset(5.0));
        bench_real("Sin", &original, &mut results, |mut v|v.sin());
        bench_real("Log", &original, &mut results, |mut v|v.log(10.0));
        bench_real("Powf", &original, &mut results, |mut v|v.powf(5.0));
        bench_real("Sqrt", &original, &mut results, |mut v|v.sqrt());
    }

	// Print
	print!("Sizes, ");
	for value in &data_sizes {
		print!("{:?}, ", value);
	}
	println!("");
	let mut sorted: Vec<_> = results.keys().map(|x|x.clone()).collect();
	sorted.sort();
	for key in &sorted {
		print!("{:?} [ns], ", key);
		for value in &results[key] {
			print!("{:?}, ", value);
		}
		println!("");
	}
}
<|endoftext|>


<commit_before>use crate::ffi::CStr;
use crate::io;
use crate::sys::{unsupported, Void};
use crate::time::Duration;

pub struct Thread(Void);

pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;

impl Thread {
    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
    pub unsafe fn new(_stack: usize, _p: Box<dyn FnOnce()>) -> io::Result<Thread> {
        unsupported()
    }

    pub fn yield_now() {
        // do nothing
    }

    pub fn set_name(_name: &CStr) {
        // nope
    }

    #[cfg(not(target_feature = "atomics"))]
    pub fn sleep(_dur: Duration) {
        panic!("can't sleep");
    }

    #[cfg(target_feature = "atomics")]
    pub fn sleep(dur: Duration) {
        use crate::arch::wasm32;
        use crate::cmp;

        // Use an atomic wait to block the current thread artificially with a
        // timeout listed. Note that we should never be notified (return value
        // of 0) or our comparison should never fail (return value of 1) so we
        // should always only resume execution through a timeout (return value
        // 2).
        let mut nanos = dur.as_nanos();
        while nanos > 0 {
            let amt = cmp::min(i64::MAX as u128, nanos);
            let mut x = 0;
            let val = unsafe { wasm32::memory_atomic_wait32(&mut x, 0, amt as i64) };
            debug_assert_eq!(val, 2);
            nanos -= amt;
        }
    }

    pub fn join(self) {
        match self.0 {}
    }
}

pub mod guard {
    pub type Guard = !;
    pub unsafe fn current() -> Option<Guard> {
        None
    }
    pub unsafe fn init() -> Option<Guard> {
        None
    }
}

// This is only used by atomics primitives when the `atomics` feature is
// enabled. In that mode we currently just use our own thread-local to store our
// current thread's ID, and then we lazily initialize it to something allocated
// from a global counter.
#[cfg(target_feature = "atomics")]
pub fn my_id() -> u32 {
    use crate::sync::atomic::{AtomicU32, Ordering::SeqCst};

    static NEXT_ID: AtomicU32 = AtomicU32::new(0);

    #[thread_local]
    static mut MY_ID: u32 = 0;

    unsafe {
        // If our thread ID isn't set yet then we need to allocate one. Do so
        // with with a simple "atomically add to a global counter" strategy.
        // This strategy doesn't handled what happens when the counter
        // overflows, however, so just abort everything once the counter
        // overflows and eventually we could have some sort of recycling scheme
        // (or maybe this is all totally irrelevant by that point!). In any case
        // though we're using a CAS loop instead of a `fetch_add` to ensure that
        // the global counter never overflows.
        if MY_ID == 0 {
            let mut cur = NEXT_ID.load(SeqCst);
            MY_ID = loop {
                let next = cur.checked_add(1).unwrap_or_else(|| crate::arch::wasm32::unreachable());
                match NEXT_ID.compare_exchange(cur, next, SeqCst, SeqCst) {
                    Ok(_) => break next,
                    Err(i) => cur = i,
                }
            };
        }
        MY_ID
    }
}
<commit_msg>sys: use `process::abort()` instead of `arch::wasm32::unreachable()`<commit_after>use crate::ffi::CStr;
use crate::io;
use crate::sys::{unsupported, Void};
use crate::time::Duration;

pub struct Thread(Void);

pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;

impl Thread {
    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
    pub unsafe fn new(_stack: usize, _p: Box<dyn FnOnce()>) -> io::Result<Thread> {
        unsupported()
    }

    pub fn yield_now() {
        // do nothing
    }

    pub fn set_name(_name: &CStr) {
        // nope
    }

    #[cfg(not(target_feature = "atomics"))]
    pub fn sleep(_dur: Duration) {
        panic!("can't sleep");
    }

    #[cfg(target_feature = "atomics")]
    pub fn sleep(dur: Duration) {
        use crate::arch::wasm32;
        use crate::cmp;

        // Use an atomic wait to block the current thread artificially with a
        // timeout listed. Note that we should never be notified (return value
        // of 0) or our comparison should never fail (return value of 1) so we
        // should always only resume execution through a timeout (return value
        // 2).
        let mut nanos = dur.as_nanos();
        while nanos > 0 {
            let amt = cmp::min(i64::MAX as u128, nanos);
            let mut x = 0;
            let val = unsafe { wasm32::memory_atomic_wait32(&mut x, 0, amt as i64) };
            debug_assert_eq!(val, 2);
            nanos -= amt;
        }
    }

    pub fn join(self) {
        match self.0 {}
    }
}

pub mod guard {
    pub type Guard = !;
    pub unsafe fn current() -> Option<Guard> {
        None
    }
    pub unsafe fn init() -> Option<Guard> {
        None
    }
}

// This is only used by atomics primitives when the `atomics` feature is
// enabled. In that mode we currently just use our own thread-local to store our
// current thread's ID, and then we lazily initialize it to something allocated
// from a global counter.
#[cfg(target_feature = "atomics")]
pub fn my_id() -> u32 {
    use crate::sync::atomic::{AtomicU32, Ordering::SeqCst};

    static NEXT_ID: AtomicU32 = AtomicU32::new(0);

    #[thread_local]
    static mut MY_ID: u32 = 0;

    unsafe {
        // If our thread ID isn't set yet then we need to allocate one. Do so
        // with with a simple "atomically add to a global counter" strategy.
        // This strategy doesn't handled what happens when the counter
        // overflows, however, so just abort everything once the counter
        // overflows and eventually we could have some sort of recycling scheme
        // (or maybe this is all totally irrelevant by that point!). In any case
        // though we're using a CAS loop instead of a `fetch_add` to ensure that
        // the global counter never overflows.
        if MY_ID == 0 {
            let mut cur = NEXT_ID.load(SeqCst);
            MY_ID = loop {
                let next = cur.checked_add(1).unwrap_or_else(|| crate::process::abort());
                match NEXT_ID.compare_exchange(cur, next, SeqCst, SeqCst) {
                    Ok(_) => break next,
                    Err(i) => cur = i,
                }
            };
        }
        MY_ID
    }
}
<|endoftext|>


<commit_before>extern crate rand;
#[macro_use]
extern crate serde_derive;
extern crate serde_qs as qs;
extern crate serde_urlencoded as urlencoded;

use rand::Rng;
use std::collections::HashMap;

use qs::Config;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
struct Address {
    city: String,
    postcode: String,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
struct QueryParams {
    id: u8,
    name: String,
    address: Address,
    phone: u32,
    user_ids: Vec<u8>,
}

fn main() {
    // Encodes as:
    // "user_ids%5B3%5D=4&user_ids%5B2%5D=3&address%5Bcity%5D=Carrot+City&\
    // id=42&address%5Bpostcode%5D=12345&name=Acme&user_ids%5B0%5D=1&\
    // phone=12345&user_ids%5B1%5D=2"
    let example_params = QueryParams {
        id: 42,
        name: "Acme".to_string(),
        phone: 12345,
        address: Address {
            city: "Carrot City".to_string(),
            postcode: "12345".to_string(),
        },
        user_ids: vec![1, 2, 3, 4],
    };

    // Naive approach: manually parameters in a map. Painful.
    let mut map = HashMap::<&str, &str>::new();
    map.insert("id", "42");
    map.insert("name", "Acme");
    map.insert("phone", "12345");
    map.insert("address[city]", "Carrot City");
    map.insert("address[postcode]", "12345");
    map.insert("user_ids[0]", "1");
    map.insert("user_ids[1]", "2");
    map.insert("user_ids[2]", "3");
    map.insert("user_ids[3]", "4");

    // Note this will be in some random order due to ordering of keys in map.
    let encoded = qs::to_string(&map).unwrap();
    println!("`serde_qs` to_string for map:\n\t{}", encoded);

    // In this form, can also simply use `serde_urlencoded`:
    let encoded = urlencoded::to_string(&map).unwrap();
    println!("`serde_urlencoded` to_string for map:\n\t{}", encoded);
    println!("");

    // Given this encoded string, you can recover the original map
    // as a list of pairs using serde_urlencoded:
    let pairs: Vec<(String, String)> = urlencoded::from_str(&encoded).unwrap();
    println!("`serde_urlencoded` from_str to pairs:\n\t{:?}", pairs);

    // However, the best way is to use serde_qs to deserialize the entire thing
    // into a struct:
    //
    // (For this round trip to work, it's necessary to parse the query string
    // in non-strict mode, to allow parsing of url_encoded square brackets
    // in the key. See the lib.rs documentation for why).
    let qs_non_strict = Config::new(5, false);
    let params: QueryParams = qs_non_strict.deserialize_str(&encoded).unwrap();
    assert_eq!(params, example_params);
    println!("`serde_qs` from_str to struct:\n\t{:?}", params);

    // Similarly, we can serialize this structure using `serde_qs`:
    let encoded = qs::to_string(&params).unwrap();
    println!("`serde_qs` to_string for struct:\n\t{:?}", encoded);
    println!("");

    // One nice feature is that this gives deterministic encodings:
    let encoded2 = qs::to_string(&params).unwrap();
    assert_eq!(encoded, encoded2);

    // An advantage of `serde_qs` for deserializing, is that it is robust
    // against different orderings of inputs:

    let mut inputs = vec![
        "id=42",
        "name=Acme",
        "phone=12345",
        "address[city]=Carrot+City",
        "address[postcode]=12345",
        "user_ids[0]=1",
        "user_ids[1]=2",
        "user_ids[2]=3",
        "user_ids[3]=4",
    ];

    let mut rng = rand::thread_rng();
    for _ in 0..10 {
        let mut acc = String::new();
        rng.shuffle(&mut inputs);
        for input in &inputs {
            acc += input;
            acc += "&";
        }
        // remove trailing character
        acc.pop();
        let params: QueryParams = qs::from_str(&acc).unwrap();
        assert_eq!(params, example_params);
    }

    // By default, `serde_qs` uses arrays with indices to denote position.
    // However, if omitted, will use input order:
    let encoded = "id=42&name=Acme&phone=12345&address[city]=Carrot+City&\
                   address[postcode]=12345&\
                   user_ids[]=1&\
                   user_ids[]=2&\
                   user_ids[]=3&\
                   user_ids[]=4";
    let params: QueryParams = qs::from_str(encoded).unwrap();
    assert_eq!(params, example_params);

    // Indices do not necessarily need to be continuous:
    let encoded = "id=42&name=Acme&phone=12345&address[city]=Carrot+City&\
                   address[postcode]=12345&\
                   user_ids[1]=2&\
                   user_ids[0]=1&\
                   user_ids[12]=3&\
                   user_ids[512]=4";
    let params: QueryParams = qs::from_str(encoded).unwrap();
    assert_eq!(params, example_params);

    // Enums are now fully supported! Most formats should work with varying
    // results.
    #[derive(Deserialize, Debug, PartialEq, Serialize)]
    enum AdjTaggedEnum {
        A,
        B(bool),
        S(String),
        V { id: u8, v: String },
    }

    #[derive(Deserialize, Debug, PartialEq, Serialize)]
    struct EnumQuery {
        e: AdjTaggedEnum,
    }

    let example_params = EnumQuery {
        e: AdjTaggedEnum::B(false),
    };
    // encodes as:
    //   "e[B]=false"
    let encoded = qs::to_string(&example_params).unwrap();
    println!("`serde_qs` to_string for enum:\n\t{:?}", encoded);
    let params: EnumQuery = qs::from_str(&encoded).unwrap();
    println!("`serde_qs` from_str for enum:\n\t{:?}", params);
    println!("");

    let example_params = EnumQuery {
        e: AdjTaggedEnum::A,
    };
    // encodes as:
    //   "e=A"
    let encoded = qs::to_string(&example_params).unwrap();
    println!("`serde_qs` to_string for enum:\n\t{:?}", encoded);
    let params: EnumQuery = qs::from_str(&encoded).unwrap();
    println!("`serde_qs` from_str for enum:\n\t{:?}", params);
    println!("");
}
<commit_msg>silence rand warning<commit_after>extern crate rand;
#[macro_use]
extern crate serde_derive;
extern crate serde_qs as qs;
extern crate serde_urlencoded as urlencoded;

use rand::seq::SliceRandom;
use std::collections::HashMap;

use qs::Config;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
struct Address {
    city: String,
    postcode: String,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
struct QueryParams {
    id: u8,
    name: String,
    address: Address,
    phone: u32,
    user_ids: Vec<u8>,
}

fn main() {
    // Encodes as:
    // "user_ids%5B3%5D=4&user_ids%5B2%5D=3&address%5Bcity%5D=Carrot+City&\
    // id=42&address%5Bpostcode%5D=12345&name=Acme&user_ids%5B0%5D=1&\
    // phone=12345&user_ids%5B1%5D=2"
    let example_params = QueryParams {
        id: 42,
        name: "Acme".to_string(),
        phone: 12345,
        address: Address {
            city: "Carrot City".to_string(),
            postcode: "12345".to_string(),
        },
        user_ids: vec![1, 2, 3, 4],
    };

    // Naive approach: manually parameters in a map. Painful.
    let mut map = HashMap::<&str, &str>::new();
    map.insert("id", "42");
    map.insert("name", "Acme");
    map.insert("phone", "12345");
    map.insert("address[city]", "Carrot City");
    map.insert("address[postcode]", "12345");
    map.insert("user_ids[0]", "1");
    map.insert("user_ids[1]", "2");
    map.insert("user_ids[2]", "3");
    map.insert("user_ids[3]", "4");

    // Note this will be in some random order due to ordering of keys in map.
    let encoded = qs::to_string(&map).unwrap();
    println!("`serde_qs` to_string for map:\n\t{}", encoded);

    // In this form, can also simply use `serde_urlencoded`:
    let encoded = urlencoded::to_string(&map).unwrap();
    println!("`serde_urlencoded` to_string for map:\n\t{}", encoded);
    println!("");

    // Given this encoded string, you can recover the original map
    // as a list of pairs using serde_urlencoded:
    let pairs: Vec<(String, String)> = urlencoded::from_str(&encoded).unwrap();
    println!("`serde_urlencoded` from_str to pairs:\n\t{:?}", pairs);

    // However, the best way is to use serde_qs to deserialize the entire thing
    // into a struct:
    //
    // (For this round trip to work, it's necessary to parse the query string
    // in non-strict mode, to allow parsing of url_encoded square brackets
    // in the key. See the lib.rs documentation for why).
    let qs_non_strict = Config::new(5, false);
    let params: QueryParams = qs_non_strict.deserialize_str(&encoded).unwrap();
    assert_eq!(params, example_params);
    println!("`serde_qs` from_str to struct:\n\t{:?}", params);

    // Similarly, we can serialize this structure using `serde_qs`:
    let encoded = qs::to_string(&params).unwrap();
    println!("`serde_qs` to_string for struct:\n\t{:?}", encoded);
    println!("");

    // One nice feature is that this gives deterministic encodings:
    let encoded2 = qs::to_string(&params).unwrap();
    assert_eq!(encoded, encoded2);

    // An advantage of `serde_qs` for deserializing, is that it is robust
    // against different orderings of inputs:

    let mut inputs = vec![
        "id=42",
        "name=Acme",
        "phone=12345",
        "address[city]=Carrot+City",
        "address[postcode]=12345",
        "user_ids[0]=1",
        "user_ids[1]=2",
        "user_ids[2]=3",
        "user_ids[3]=4",
    ];

    let mut rng = rand::thread_rng();
    for _ in 0..10 {
        let mut acc = String::new();
        inputs.shuffle(&mut rng);
        for input in &inputs {
            acc += input;
            acc += "&";
        }
        // remove trailing character
        acc.pop();
        let params: QueryParams = qs::from_str(&acc).unwrap();
        assert_eq!(params, example_params);
    }

    // By default, `serde_qs` uses arrays with indices to denote position.
    // However, if omitted, will use input order:
    let encoded = "id=42&name=Acme&phone=12345&address[city]=Carrot+City&\
                   address[postcode]=12345&\
                   user_ids[]=1&\
                   user_ids[]=2&\
                   user_ids[]=3&\
                   user_ids[]=4";
    let params: QueryParams = qs::from_str(encoded).unwrap();
    assert_eq!(params, example_params);

    // Indices do not necessarily need to be continuous:
    let encoded = "id=42&name=Acme&phone=12345&address[city]=Carrot+City&\
                   address[postcode]=12345&\
                   user_ids[1]=2&\
                   user_ids[0]=1&\
                   user_ids[12]=3&\
                   user_ids[512]=4";
    let params: QueryParams = qs::from_str(encoded).unwrap();
    assert_eq!(params, example_params);

    // Enums are now fully supported! Most formats should work with varying
    // results.
    #[derive(Deserialize, Debug, PartialEq, Serialize)]
    enum AdjTaggedEnum {
        A,
        B(bool),
        S(String),
        V { id: u8, v: String },
    }

    #[derive(Deserialize, Debug, PartialEq, Serialize)]
    struct EnumQuery {
        e: AdjTaggedEnum,
    }

    let example_params = EnumQuery {
        e: AdjTaggedEnum::B(false),
    };
    // encodes as:
    //   "e[B]=false"
    let encoded = qs::to_string(&example_params).unwrap();
    println!("`serde_qs` to_string for enum:\n\t{:?}", encoded);
    let params: EnumQuery = qs::from_str(&encoded).unwrap();
    println!("`serde_qs` from_str for enum:\n\t{:?}", params);
    println!("");

    let example_params = EnumQuery {
        e: AdjTaggedEnum::A,
    };
    // encodes as:
    //   "e=A"
    let encoded = qs::to_string(&example_params).unwrap();
    println!("`serde_qs` to_string for enum:\n\t{:?}", encoded);
    let params: EnumQuery = qs::from_str(&encoded).unwrap();
    println!("`serde_qs` from_str for enum:\n\t{:?}", params);
    println!("");
}
<|endoftext|>


<commit_before>#![allow(clippy::blacklisted_name)]

use askama::{SizedTemplate, Template};

use std::collections::HashMap;

#[derive(Template)]
#[template(path = "simple.html")]
struct VariablesTemplate<'a> {
    strvar: &'a str,
    num: i64,
    i18n: String,
}

#[test]
fn test_variables() {
    let s = VariablesTemplate {
        strvar: "foo",
        num: 42,
        i18n: "Iñtërnâtiônàlizætiøn".to_string(),
    };
    assert_eq!(
        s.render().unwrap(),
        "\nhello world, foo\n\
         with number: 42\n\
         Iñtërnâtiônàlizætiøn is important\n\
         in vars too: Iñtërnâtiônàlizætiøn"
    );
    assert_eq!(
        <VariablesTemplate as SizedTemplate>::extension(),
        Some("html")
    );
}

#[derive(Template)]
#[template(path = "hello.html")]
struct EscapeTemplate<'a> {
    name: &'a str,
}

#[test]
fn test_escape() {
    let s = EscapeTemplate { name: "<>&\"'/" };

    assert_eq!(
        s.render().unwrap(),
        "Hello, <>&"'/!"
    );
}

#[derive(Template)]
#[template(path = "simple-no-escape.txt")]
struct VariablesTemplateNoEscape<'a> {
    strvar: &'a str,
    num: i64,
    i18n: String,
}

#[test]
fn test_variables_no_escape() {
    let s = VariablesTemplateNoEscape {
        strvar: "foo",
        num: 42,
        i18n: "Iñtërnâtiônàlizætiøn".to_string(),
    };
    assert_eq!(
        s.render().unwrap(),
        "\nhello world, foo\n\
         with number: 42\n\
         Iñtërnâtiônàlizætiøn is important\n\
         in vars too: Iñtërnâtiônàlizætiøn"
    );
}

#[derive(Template)]
#[template(path = "if.html")]
struct IfTemplate {
    cond: bool,
}

#[test]
fn test_if() {
    let s = IfTemplate { cond: true };
    assert_eq!(s.render().unwrap(), "true");
}

#[derive(Template)]
#[template(path = "else.html")]
struct ElseTemplate {
    cond: bool,
}

#[test]
fn test_else() {
    let s = ElseTemplate { cond: false };
    assert_eq!(s.render().unwrap(), "false");
}

#[derive(Template)]
#[template(path = "else-if.html")]
struct ElseIfTemplate {
    cond: bool,
    check: bool,
}

#[test]
fn test_else_if() {
    let s = ElseIfTemplate {
        cond: false,
        check: true,
    };
    assert_eq!(s.render().unwrap(), "checked");
}

#[derive(Template)]
#[template(path = "literals.html")]
struct LiteralsTemplate {}

#[test]
fn test_literals() {
    let s = LiteralsTemplate {};
    assert_eq!(s.render().unwrap(), "a\na\ntrue\nfalse");
}

#[derive(Template)]
#[template(path = "literals-escape.html")]
struct LiteralsEscapeTemplate {}

#[test]
fn test_literals_escape() {
    let s = LiteralsEscapeTemplate {};
    assert_eq!(
        s.render().unwrap(),
        "A\n\r\t\\\0♥'""\nA\n\r\t\\\0♥'"'"
    );
}

struct Holder {
    a: usize,
}

#[derive(Template)]
#[template(path = "attr.html")]
struct AttrTemplate {
    inner: Holder,
}

#[test]
fn test_attr() {
    let t = AttrTemplate {
        inner: Holder { a: 5 },
    };
    assert_eq!(t.render().unwrap(), "5");
}

#[derive(Template)]
#[template(path = "tuple-attr.html")]
struct TupleAttrTemplate<'a> {
    tuple: (&'a str, &'a str),
}

#[test]
fn test_tuple_attr() {
    let t = TupleAttrTemplate {
        tuple: ("foo", "bar"),
    };
    assert_eq!(t.render().unwrap(), "foobar");
}

struct NestedHolder {
    holder: Holder,
}

#[derive(Template)]
#[template(path = "nested-attr.html")]
struct NestedAttrTemplate {
    inner: NestedHolder,
}

#[test]
fn test_nested_attr() {
    let t = NestedAttrTemplate {
        inner: NestedHolder {
            holder: Holder { a: 5 },
        },
    };
    assert_eq!(t.render().unwrap(), "5");
}

#[derive(Template)]
#[template(path = "option.html")]
struct OptionTemplate<'a> {
    var: Option<&'a str>,
}

#[test]
fn test_option() {
    let some = OptionTemplate { var: Some("foo") };
    assert_eq!(some.render().unwrap(), "some: foo");
    let none = OptionTemplate { var: None };
    assert_eq!(none.render().unwrap(), "none");
}

#[derive(Template)]
#[template(path = "generics.html")]
struct GenericsTemplate<T, U = u8>
where
    T: std::fmt::Display,
    U: std::fmt::Display,
{
    t: T,
    u: U,
}

#[test]
fn test_generics() {
    let t = GenericsTemplate { t: "a", u: 42 };
    assert_eq!(t.render().unwrap(), "a42");
}

#[derive(Template)]
#[template(path = "composition.html")]
struct CompositionTemplate {
    foo: IfTemplate,
}

#[test]
fn test_composition() {
    let t = CompositionTemplate {
        foo: IfTemplate { cond: true },
    };
    assert_eq!(t.render().unwrap(), "composed: true");
}

#[derive(PartialEq, Eq)]
enum Alphabet {
    Alpha,
}

#[derive(Template)]
#[template(source = "{% if x == Alphabet::Alpha %}true{% endif %}", ext = "txt")]
struct PathCompareTemplate {
    x: Alphabet,
}

#[test]
fn test_path_compare() {
    let t = PathCompareTemplate { x: Alphabet::Alpha };
    assert_eq!(t.render().unwrap(), "true");
}

#[derive(Template)]
#[template(
    source = "{% for i in [\"a\", \"\"] %}{{ i }}{% endfor %}",
    ext = "txt"
)]
struct ArrayTemplate {}

#[test]
fn test_slice_literal() {
    let t = ArrayTemplate {};
    assert_eq!(t.render().unwrap(), "a");
}

#[derive(Template)]
#[template(source = "Hello, {{ world(\"123\", 4) }}!", ext = "txt")]
struct FunctionRefTemplate {
    world: fn(s: &str, v: u8) -> String,
}

#[test]
fn test_func_ref_call() {
    let t = FunctionRefTemplate {
        world: |s, r| format!("world({}, {})", s, r),
    };
    assert_eq!(t.render().unwrap(), "Hello, world(123, 4)!");
}

#[allow(clippy::trivially_copy_pass_by_ref)]
fn world2(s: &str, v: u8) -> String {
    format!("world{}{}", v, s)
}

#[derive(Template)]
#[template(source = "Hello, {{ self::world2(\"123\", 4) }}!", ext = "txt")]
struct PathFunctionTemplate;

#[test]
fn test_path_func_call() {
    assert_eq!(PathFunctionTemplate.render().unwrap(), "Hello, world4123!");
}

#[derive(Template)]
#[template(source = "{{ ::std::string::String::from(\"123\") }}", ext = "txt")]
struct RootPathFunctionTemplate;

#[test]
fn test_root_path_func_call() {
    assert_eq!(RootPathFunctionTemplate.render().unwrap(), "123");
}

#[derive(Template)]
#[template(source = "Hello, {{ Self::world3(self, \"123\", 4) }}!", ext = "txt")]
struct FunctionTemplate;

impl FunctionTemplate {
    #[allow(clippy::trivially_copy_pass_by_ref)]
    fn world3(&self, s: &str, v: u8) -> String {
        format!("world{}{}", s, v)
    }
}

#[derive(Template)]
#[template(source = "  {# foo -#} ", ext = "txt")]
struct CommentTemplate {}

#[test]
fn test_comment() {
    let t = CommentTemplate {};
    assert_eq!(t.render().unwrap(), "  ");
}

#[derive(Template)]
#[template(source = "{% if !foo %}Hello{% endif %}", ext = "txt")]
struct NegationTemplate {
    foo: bool,
}

#[test]
fn test_negation() {
    let t = NegationTemplate { foo: false };
    assert_eq!(t.render().unwrap(), "Hello");
}

#[derive(Template)]
#[template(source = "{% if foo > -2 %}Hello{% endif %}", ext = "txt")]
struct MinusTemplate {
    foo: i8,
}

#[test]
fn test_minus() {
    let t = MinusTemplate { foo: 1 };
    assert_eq!(t.render().unwrap(), "Hello");
}

#[derive(Template)]
#[template(source = "{{ foo[\"bar\"] }}", ext = "txt")]
struct IndexTemplate {
    foo: HashMap<String, String>,
}

#[test]
fn test_index() {
    let mut foo = HashMap::new();
    foo.insert("bar".into(), "baz".into());
    let t = IndexTemplate { foo };
    assert_eq!(t.render().unwrap(), "baz");
}

#[derive(Template)]
#[template(source = "foo", ext = "txt")]
struct Empty;

#[test]
fn test_empty() {
    assert_eq!(Empty.render().unwrap(), "foo");
}

#[derive(Template)]
#[template(path = "raw-simple.html")]
struct RawTemplate;

#[test]
fn test_raw_simple() {
    let template = RawTemplate;
    assert_eq!(template.render().unwrap(), "\n{{ name }}\n");
}

#[derive(Template)]
#[template(path = "raw-complex.html")]
struct RawTemplateComplex;

#[test]
fn test_raw_complex() {
    let template = RawTemplateComplex;
    assert_eq!(
        template.render().unwrap(),
        "\n{% block name %}\n  {{ name }}\n{% endblock %}\n"
    );
}

mod without_import_on_derive {
    #[derive(askama::Template)]
    #[template(source = "foo", ext = "txt")]
    struct WithoutImport;

    #[test]
    fn test_without_import() {
        use askama::Template;
        assert_eq!(WithoutImport.render().unwrap(), "foo");
    }
}

#[derive(askama::Template)]
#[template(source = "{% let s = String::new() %}{{ s }}", ext = "txt")]
struct DefineStringVar;

#[test]
fn test_define_string_var() {
    let template = DefineStringVar;
    assert_eq!(template.render().unwrap(), "");
}
<commit_msg>Added constants test<commit_after>#![allow(clippy::blacklisted_name)]

use askama::{SizedTemplate, Template};

use std::collections::HashMap;

#[derive(Template)]
#[template(path = "simple.html")]
struct VariablesTemplate<'a> {
    strvar: &'a str,
    num: i64,
    i18n: String,
}

#[test]
fn test_variables() {
    let s = VariablesTemplate {
        strvar: "foo",
        num: 42,
        i18n: "Iñtërnâtiônàlizætiøn".to_string(),
    };
    assert_eq!(
        s.render().unwrap(),
        "\nhello world, foo\n\
         with number: 42\n\
         Iñtërnâtiônàlizætiøn is important\n\
         in vars too: Iñtërnâtiônàlizætiøn"
    );
    assert_eq!(
        <VariablesTemplate as SizedTemplate>::extension(),
        Some("html")
    );
}

#[derive(Template)]
#[template(path = "hello.html")]
struct EscapeTemplate<'a> {
    name: &'a str,
}

#[test]
fn test_escape() {
    let s = EscapeTemplate { name: "<>&\"'/" };

    assert_eq!(
        s.render().unwrap(),
        "Hello, <>&"'/!"
    );
}

#[derive(Template)]
#[template(path = "simple-no-escape.txt")]
struct VariablesTemplateNoEscape<'a> {
    strvar: &'a str,
    num: i64,
    i18n: String,
}

#[test]
fn test_variables_no_escape() {
    let s = VariablesTemplateNoEscape {
        strvar: "foo",
        num: 42,
        i18n: "Iñtërnâtiônàlizætiøn".to_string(),
    };
    assert_eq!(
        s.render().unwrap(),
        "\nhello world, foo\n\
         with number: 42\n\
         Iñtërnâtiônàlizætiøn is important\n\
         in vars too: Iñtërnâtiônàlizætiøn"
    );
}

#[derive(Template)]
#[template(
    source = "{{ foo }} {{ foo_bar }} {{ FOO }} {{ FOO_BAR }} {{ self::FOO }} {{ self::FOO_BAR }} {{ Self::BAR }} {{ Self::BAR_BAZ }}",
    ext = "txt"
)]
struct ConstTemplate {
    foo: &'static str,
    foo_bar: &'static str,
}

impl ConstTemplate {
    const BAR: &'static str = "BAR";
    const BAR_BAZ: &'static str = "BAR BAZ";
}

#[test]
fn test_constants() {
    let t = ConstTemplate {
        foo: "foo",
        foo_bar: "foo bar",
    };
    assert_eq!(
        t.render().unwrap(),
        "foo foo bar FOO FOO BAR FOO FOO BAR BAR BAR BAZ"
    );
}

const FOO: &str = "FOO";
const FOO_BAR: &str = "FOO BAR";

#[derive(Template)]
#[template(path = "if.html")]
struct IfTemplate {
    cond: bool,
}

#[test]
fn test_if() {
    let s = IfTemplate { cond: true };
    assert_eq!(s.render().unwrap(), "true");
}

#[derive(Template)]
#[template(path = "else.html")]
struct ElseTemplate {
    cond: bool,
}

#[test]
fn test_else() {
    let s = ElseTemplate { cond: false };
    assert_eq!(s.render().unwrap(), "false");
}

#[derive(Template)]
#[template(path = "else-if.html")]
struct ElseIfTemplate {
    cond: bool,
    check: bool,
}

#[test]
fn test_else_if() {
    let s = ElseIfTemplate {
        cond: false,
        check: true,
    };
    assert_eq!(s.render().unwrap(), "checked");
}

#[derive(Template)]
#[template(path = "literals.html")]
struct LiteralsTemplate {}

#[test]
fn test_literals() {
    let s = LiteralsTemplate {};
    assert_eq!(s.render().unwrap(), "a\na\ntrue\nfalse");
}

#[derive(Template)]
#[template(path = "literals-escape.html")]
struct LiteralsEscapeTemplate {}

#[test]
fn test_literals_escape() {
    let s = LiteralsEscapeTemplate {};
    assert_eq!(
        s.render().unwrap(),
        "A\n\r\t\\\0♥'""\nA\n\r\t\\\0♥'"'"
    );
}

struct Holder {
    a: usize,
}

#[derive(Template)]
#[template(path = "attr.html")]
struct AttrTemplate {
    inner: Holder,
}

#[test]
fn test_attr() {
    let t = AttrTemplate {
        inner: Holder { a: 5 },
    };
    assert_eq!(t.render().unwrap(), "5");
}

#[derive(Template)]
#[template(path = "tuple-attr.html")]
struct TupleAttrTemplate<'a> {
    tuple: (&'a str, &'a str),
}

#[test]
fn test_tuple_attr() {
    let t = TupleAttrTemplate {
        tuple: ("foo", "bar"),
    };
    assert_eq!(t.render().unwrap(), "foobar");
}

struct NestedHolder {
    holder: Holder,
}

#[derive(Template)]
#[template(path = "nested-attr.html")]
struct NestedAttrTemplate {
    inner: NestedHolder,
}

#[test]
fn test_nested_attr() {
    let t = NestedAttrTemplate {
        inner: NestedHolder {
            holder: Holder { a: 5 },
        },
    };
    assert_eq!(t.render().unwrap(), "5");
}

#[derive(Template)]
#[template(path = "option.html")]
struct OptionTemplate<'a> {
    var: Option<&'a str>,
}

#[test]
fn test_option() {
    let some = OptionTemplate { var: Some("foo") };
    assert_eq!(some.render().unwrap(), "some: foo");
    let none = OptionTemplate { var: None };
    assert_eq!(none.render().unwrap(), "none");
}

#[derive(Template)]
#[template(path = "generics.html")]
struct GenericsTemplate<T, U = u8>
where
    T: std::fmt::Display,
    U: std::fmt::Display,
{
    t: T,
    u: U,
}

#[test]
fn test_generics() {
    let t = GenericsTemplate { t: "a", u: 42 };
    assert_eq!(t.render().unwrap(), "a42");
}

#[derive(Template)]
#[template(path = "composition.html")]
struct CompositionTemplate {
    foo: IfTemplate,
}

#[test]
fn test_composition() {
    let t = CompositionTemplate {
        foo: IfTemplate { cond: true },
    };
    assert_eq!(t.render().unwrap(), "composed: true");
}

#[derive(PartialEq, Eq)]
enum Alphabet {
    Alpha,
}

#[derive(Template)]
#[template(source = "{% if x == Alphabet::Alpha %}true{% endif %}", ext = "txt")]
struct PathCompareTemplate {
    x: Alphabet,
}

#[test]
fn test_path_compare() {
    let t = PathCompareTemplate { x: Alphabet::Alpha };
    assert_eq!(t.render().unwrap(), "true");
}

#[derive(Template)]
#[template(
    source = "{% for i in [\"a\", \"\"] %}{{ i }}{% endfor %}",
    ext = "txt"
)]
struct ArrayTemplate {}

#[test]
fn test_slice_literal() {
    let t = ArrayTemplate {};
    assert_eq!(t.render().unwrap(), "a");
}

#[derive(Template)]
#[template(source = "Hello, {{ world(\"123\", 4) }}!", ext = "txt")]
struct FunctionRefTemplate {
    world: fn(s: &str, v: u8) -> String,
}

#[test]
fn test_func_ref_call() {
    let t = FunctionRefTemplate {
        world: |s, r| format!("world({}, {})", s, r),
    };
    assert_eq!(t.render().unwrap(), "Hello, world(123, 4)!");
}

#[allow(clippy::trivially_copy_pass_by_ref)]
fn world2(s: &str, v: u8) -> String {
    format!("world{}{}", v, s)
}

#[derive(Template)]
#[template(source = "Hello, {{ self::world2(\"123\", 4) }}!", ext = "txt")]
struct PathFunctionTemplate;

#[test]
fn test_path_func_call() {
    assert_eq!(PathFunctionTemplate.render().unwrap(), "Hello, world4123!");
}

#[derive(Template)]
#[template(source = "{{ ::std::string::String::from(\"123\") }}", ext = "txt")]
struct RootPathFunctionTemplate;

#[test]
fn test_root_path_func_call() {
    assert_eq!(RootPathFunctionTemplate.render().unwrap(), "123");
}

#[derive(Template)]
#[template(source = "Hello, {{ Self::world3(self, \"123\", 4) }}!", ext = "txt")]
struct FunctionTemplate;

impl FunctionTemplate {
    #[allow(clippy::trivially_copy_pass_by_ref)]
    fn world3(&self, s: &str, v: u8) -> String {
        format!("world{}{}", s, v)
    }
}

#[derive(Template)]
#[template(source = "  {# foo -#} ", ext = "txt")]
struct CommentTemplate {}

#[test]
fn test_comment() {
    let t = CommentTemplate {};
    assert_eq!(t.render().unwrap(), "  ");
}

#[derive(Template)]
#[template(source = "{% if !foo %}Hello{% endif %}", ext = "txt")]
struct NegationTemplate {
    foo: bool,
}

#[test]
fn test_negation() {
    let t = NegationTemplate { foo: false };
    assert_eq!(t.render().unwrap(), "Hello");
}

#[derive(Template)]
#[template(source = "{% if foo > -2 %}Hello{% endif %}", ext = "txt")]
struct MinusTemplate {
    foo: i8,
}

#[test]
fn test_minus() {
    let t = MinusTemplate { foo: 1 };
    assert_eq!(t.render().unwrap(), "Hello");
}

#[derive(Template)]
#[template(source = "{{ foo[\"bar\"] }}", ext = "txt")]
struct IndexTemplate {
    foo: HashMap<String, String>,
}

#[test]
fn test_index() {
    let mut foo = HashMap::new();
    foo.insert("bar".into(), "baz".into());
    let t = IndexTemplate { foo };
    assert_eq!(t.render().unwrap(), "baz");
}

#[derive(Template)]
#[template(source = "foo", ext = "txt")]
struct Empty;

#[test]
fn test_empty() {
    assert_eq!(Empty.render().unwrap(), "foo");
}

#[derive(Template)]
#[template(path = "raw-simple.html")]
struct RawTemplate;

#[test]
fn test_raw_simple() {
    let template = RawTemplate;
    assert_eq!(template.render().unwrap(), "\n{{ name }}\n");
}

#[derive(Template)]
#[template(path = "raw-complex.html")]
struct RawTemplateComplex;

#[test]
fn test_raw_complex() {
    let template = RawTemplateComplex;
    assert_eq!(
        template.render().unwrap(),
        "\n{% block name %}\n  {{ name }}\n{% endblock %}\n"
    );
}

mod without_import_on_derive {
    #[derive(askama::Template)]
    #[template(source = "foo", ext = "txt")]
    struct WithoutImport;

    #[test]
    fn test_without_import() {
        use askama::Template;
        assert_eq!(WithoutImport.render().unwrap(), "foo");
    }
}

#[derive(askama::Template)]
#[template(source = "{% let s = String::new() %}{{ s }}", ext = "txt")]
struct DefineStringVar;

#[test]
fn test_define_string_var() {
    let template = DefineStringVar;
    assert_eq!(template.render().unwrap(), "");
}
<|endoftext|>


<commit_before>extern crate tempdir;

use self::tempdir::TempDir;
use super::mpd;
use std::fs::{File, create_dir};
use std::io::Write;
use std::os::unix::net::UnixStream;
use std::path::{Path, PathBuf};
use std::process::{Command, Child};

struct MpdConfig {
    db_file: PathBuf,
    music_directory: PathBuf,
    playlist_directory: PathBuf,
    config_path: PathBuf,
    sock_path: PathBuf,
}

impl MpdConfig {
    pub fn new<P>(base: P) -> MpdConfig
        where P: AsRef<Path>
    {
        let base = base.as_ref();
        MpdConfig {
            db_file: base.join("db"),
            music_directory: base.join("music"),
            playlist_directory: base.join("playlists"),
            config_path: base.join("config"),
            sock_path: base.join("sock"),
        }
    }

    fn config_text(&self) -> String {
        format!(r#"
db_file "{db_file}"
log_file "/dev/null"
music_directory "{music_directory}"
playlist_directory "{playlist_directory}"
bind_to_address "{sock_path}"
audio_output {{
    type "null"
    name "null"
}}
"#,
            db_file=self.db_file.display(),
            music_directory=self.music_directory.display(),
            playlist_directory=self.playlist_directory.display(),
            sock_path=self.sock_path.display(),
        )
    }

    fn generate(&self) {
        create_dir(&self.music_directory).expect("Could not create music directory.");
        create_dir(&self.playlist_directory).expect("Could not create playlist directory.");
        let mut file = File::create(&self.config_path).expect("Could not create config file.");
        file.write_all(self.config_text().as_bytes()).expect("Could not write config file.");
    }
}

pub struct Daemon {
    // Saved here so it gets dropped when this does.
    _temp_dir: TempDir,
    config: MpdConfig,
    process: Child,
}

impl Drop for Daemon {
    fn drop(&mut self) {
        self.process.kill().expect("Could not kill mpd daemon.");
        self.process.wait().expect("Could not wait for mpd daemon to shutdown.");
    }
}

fn sleep() {
    use std::{thread, time};
    let ten_millis = time::Duration::from_millis(10);
    thread::sleep(ten_millis);
}

impl Daemon {
    pub fn start() -> Daemon {
        let temp_dir = TempDir::new("mpd-test").unwrap();
        let config = MpdConfig::new(&temp_dir);
        config.generate();
        let process = Command::new("mpd")
            .arg("--no-daemon")
            .arg(&config.config_path)
            .spawn()
            .expect("Could not create mpd daemon.");

        let daemon = Daemon {
            _temp_dir: temp_dir,
            config: config,
            process: process,
        };

        // Wait until we can connect to the daemon
        let mut client;
        loop {
            if let Ok(c) = daemon.maybe_connect() {
                client = c;
                break;
            }
            sleep()
        }
        while let Some(_) = client.status().expect("Couldn't get status.").updating_db {
            sleep()
        }

        daemon
    }

    fn maybe_connect(&self) -> Result<mpd::Client<UnixStream>, mpd::error::Error> {
        let stream = UnixStream::connect(&self.config.sock_path)?;
        mpd::Client::new(stream)
    }

    pub fn connect(&self) -> mpd::Client<UnixStream> {
        self.maybe_connect().expect("Could not connect to daemon.")
    }
}
<commit_msg>Capture output from mpd.<commit_after>extern crate tempdir;

use self::tempdir::TempDir;
use super::mpd;
use std::fs::{File, create_dir};
use std::io::{Write, Read};
use std::os::unix::net::UnixStream;
use std::path::{Path, PathBuf};
use std::process::{Command, Child, Stdio};

struct MpdConfig {
    db_file: PathBuf,
    music_directory: PathBuf,
    playlist_directory: PathBuf,
    config_path: PathBuf,
    sock_path: PathBuf,
}

impl MpdConfig {
    pub fn new<P>(base: P) -> MpdConfig
        where P: AsRef<Path>
    {
        let base = base.as_ref();
        MpdConfig {
            db_file: base.join("db"),
            music_directory: base.join("music"),
            playlist_directory: base.join("playlists"),
            config_path: base.join("config"),
            sock_path: base.join("sock"),
        }
    }

    fn config_text(&self) -> String {
        format!(r#"
db_file "{db_file}"
log_file "/dev/null"
music_directory "{music_directory}"
playlist_directory "{playlist_directory}"
bind_to_address "{sock_path}"
audio_output {{
    type "null"
    name "null"
}}
"#,
            db_file=self.db_file.display(),
            music_directory=self.music_directory.display(),
            playlist_directory=self.playlist_directory.display(),
            sock_path=self.sock_path.display(),
        )
    }

    fn generate(&self) {
        create_dir(&self.music_directory).expect("Could not create music directory.");
        create_dir(&self.playlist_directory).expect("Could not create playlist directory.");
        let mut file = File::create(&self.config_path).expect("Could not create config file.");
        file.write_all(self.config_text().as_bytes()).expect("Could not write config file.");
    }
}

pub struct Daemon {
    // Saved here so it gets dropped when this does.
    _temp_dir: TempDir,
    config: MpdConfig,
    process: Child,
}

impl Drop for Daemon {
    fn drop(&mut self) {
        self.process.kill().expect("Could not kill mpd daemon.");
        self.process.wait().expect("Could not wait for mpd daemon to shutdown.");
        if let Some(ref mut stderr) = self.process.stderr {
            let mut output = String::new();
            stderr.read_to_string(&mut output).expect("Could not collect output from mpd.");
            println!{"Output from mpd:"}
            println!{"{}", output};
        }
    }
}

fn sleep() {
    use std::{thread, time};
    let ten_millis = time::Duration::from_millis(10);
    thread::sleep(ten_millis);
}

impl Daemon {
    pub fn start() -> Daemon {
        let temp_dir = TempDir::new("mpd-test").unwrap();
        let config = MpdConfig::new(&temp_dir);
        config.generate();
        let process = Command::new("mpd")
            .arg("--no-daemon")
            .arg(&config.config_path)
            .stdin(Stdio::null())
            .stdout(Stdio::null())
            .stderr(Stdio::piped())
            .spawn()
            .expect("Could not create mpd daemon.");

        let daemon = Daemon {
            _temp_dir: temp_dir,
            config: config,
            process: process,
        };

        // Wait until we can connect to the daemon
        let mut client;
        loop {
            if let Ok(c) = daemon.maybe_connect() {
                client = c;
                break;
            }
            sleep()
        }
        while let Some(_) = client.status().expect("Couldn't get status.").updating_db {
            sleep()
        }

        daemon
    }

    fn maybe_connect(&self) -> Result<mpd::Client<UnixStream>, mpd::error::Error> {
        let stream = UnixStream::connect(&self.config.sock_path)?;
        mpd::Client::new(stream)
    }

    pub fn connect(&self) -> mpd::Client<UnixStream> {
        self.maybe_connect().expect("Could not connect to daemon.")
    }
}
<|endoftext|>