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

use libc::{c_int};
use std::boxed;
use std::mem;
use std::slice;
use string::cef_string_utf16_set;
use types::{cef_string_list_t,cef_string_t};

use rustc_unicode::str::Utf16Encoder;

//cef_string_list

#[no_mangle]
pub extern "C" fn cef_string_list_alloc() -> *mut cef_string_list_t {
    boxed::into_raw(box vec!())
}

#[no_mangle]
pub extern "C" fn cef_string_list_size(lt: *mut cef_string_list_t) -> c_int {
    unsafe {
        if lt.is_null() { return 0; }
        (*lt).len() as c_int
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_append(lt: *mut cef_string_list_t, value: *const cef_string_t) {
    unsafe {
        if lt.is_null() { return; }
        (*lt).push(String::from_utf16(slice::from_raw_parts((*value).str, (*value).length as usize)).unwrap());
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_value(lt: *mut cef_string_list_t, index: c_int, value: *mut cef_string_t) -> c_int {
    unsafe {
        if index < 0 || lt.is_null() { return 0; }
        if index as usize > (*lt).len() - 1 { return 0; }
        let ref string = (*lt)[index as usize];
        let utf16_chars: Vec<u16> = Utf16Encoder::new(string.chars()).collect();
        cef_string_utf16_set(mem::transmute(utf16_chars.as_ptr()), utf16_chars.len() as u64, value, 1)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_clear(lt: *mut cef_string_list_t) {
    unsafe {
        if lt.is_null() { return; }
        (*lt).clear();
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_free(lt: *mut cef_string_list_t) {
    unsafe {
        if lt.is_null() { return; }
        cef_string_list_clear(lt);
        drop(Box::from_raw(lt));
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_copy(lt: *mut cef_string_list_t) -> *mut cef_string_list_t {
    unsafe {
        if lt.is_null() { return 0 as *mut cef_string_list_t; }
        let copy = (*lt).clone();
        boxed::into_raw(box copy)
    }
}
<commit_msg>Remove unnecessary transmute in cef_string_list_value.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use libc::{c_int};
use std::boxed;
use std::slice;
use string::cef_string_utf16_set;
use types::{cef_string_list_t,cef_string_t};

use rustc_unicode::str::Utf16Encoder;

//cef_string_list

#[no_mangle]
pub extern "C" fn cef_string_list_alloc() -> *mut cef_string_list_t {
    boxed::into_raw(box vec!())
}

#[no_mangle]
pub extern "C" fn cef_string_list_size(lt: *mut cef_string_list_t) -> c_int {
    unsafe {
        if lt.is_null() { return 0; }
        (*lt).len() as c_int
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_append(lt: *mut cef_string_list_t, value: *const cef_string_t) {
    unsafe {
        if lt.is_null() { return; }
        (*lt).push(String::from_utf16(slice::from_raw_parts((*value).str, (*value).length as usize)).unwrap());
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_value(lt: *mut cef_string_list_t, index: c_int, value: *mut cef_string_t) -> c_int {
    unsafe {
        if index < 0 || lt.is_null() { return 0; }
        if index as usize > (*lt).len() - 1 { return 0; }
        let ref string = (*lt)[index as usize];
        let utf16_chars: Vec<u16> = Utf16Encoder::new(string.chars()).collect();
        cef_string_utf16_set(utf16_chars.as_ptr(), utf16_chars.len() as u64, value, 1)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_clear(lt: *mut cef_string_list_t) {
    unsafe {
        if lt.is_null() { return; }
        (*lt).clear();
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_free(lt: *mut cef_string_list_t) {
    unsafe {
        if lt.is_null() { return; }
        cef_string_list_clear(lt);
        drop(Box::from_raw(lt));
    }
}

#[no_mangle]
pub extern "C" fn cef_string_list_copy(lt: *mut cef_string_list_t) -> *mut cef_string_list_t {
    unsafe {
        if lt.is_null() { return 0 as *mut cef_string_list_t; }
        let copy = (*lt).clone();
        boxed::into_raw(box copy)
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 Erik Nordstrøm <erik@nordstroem.no>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

use self::Color::*;
use self::Rank::*;
use std::slice::Iter;
use std::mem;

extern crate rand;
use self::rand::Rng;

#[derive(Copy, Clone)]
pub enum Color
{
    Spades   = 1, // ♠,
    Hearts,       // ♥,
    Diamonds,     // ♦,
    Clubs,        // ♣
}

#[derive(Copy, Clone)]
pub enum Rank
{
    A     = 1,
    Two,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    Ten,
    J,
    Q,
    K
}

impl Color
{
    // https://stackoverflow.com/a/21376984
    fn iterator () -> Iter<'static, Color>
    {
        static COLORS: [Color; 4] = [Spades, Hearts, Diamonds, Clubs];
        COLORS.into_iter()
    }
}

impl Rank
{
    fn iterator () -> Iter<'static, Rank>
    {
        static RANKS: [Rank; 13] =
            [ A, Two, Three, Four, Five, Six, Seven,
              Eight, Nine, Ten, J, Q, K ] ;
        RANKS.into_iter()
    }
}

pub struct Card
{
    pub color:     Color,
    pub rank:      Rank,
    pub id:        u8,
    pub facing_up: bool
}

pub fn shuffled_deck () -> Box<[Card; 52]>
{
    // https://stackoverflow.com/a/31361031
    let all_cards = unsafe
    {
        let mut _all_cards: [Card; 52] = mem::uninitialized();

        let mut ids_available: Vec<u8> = (0..52).collect();

        // https://stackoverflow.com/a/26035435
        let mut ids_avail_slice = ids_available.as_mut_slice();
        rand::thread_rng().shuffle(ids_avail_slice);
        let mut id_iter = ids_avail_slice.iter_mut();

        for color in Color::iterator()
        {
            for rank in Rank::iterator()
            {

                let curr_id = *(id_iter.next().unwrap());

                let card = Card
                {
                    color:     *color,
                    rank:      *rank,
                    id:        curr_id,
                    facing_up: false
                };

                _all_cards[curr_id as usize] = card;
            }
        }

        _all_cards
    };

    Box::new(all_cards)
}
<commit_msg>Whitespace.<commit_after>/*
 * Copyright (c) 2017 Erik Nordstrøm <erik@nordstroem.no>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

use self::Color::*;
use self::Rank::*;
use std::slice::Iter;
use std::mem;

extern crate rand;
use self::rand::Rng;

#[derive(Copy, Clone)]
pub enum Color
{
    Spades   = 1, // ♠,
    Hearts,       // ♥,
    Diamonds,     // ♦,
    Clubs,        // ♣
}

#[derive(Copy, Clone)]
pub enum Rank
{
    A = 1, Two, Three, Four, Five, Six,
    Seven, Eight, Nine, Ten, J, Q, K
}

impl Color
{
    // https://stackoverflow.com/a/21376984
    fn iterator () -> Iter<'static, Color>
    {
        static COLORS: [Color; 4] = [Spades, Hearts, Diamonds, Clubs];
        COLORS.into_iter()
    }
}

impl Rank
{
    fn iterator () -> Iter<'static, Rank>
    {
        static RANKS: [Rank; 13] =
            [ A, Two, Three, Four, Five, Six, Seven,
              Eight, Nine, Ten, J, Q, K ] ;
        RANKS.into_iter()
    }
}

pub struct Card
{
    pub color:     Color,
    pub rank:      Rank,
    pub id:        u8,
    pub facing_up: bool
}

pub fn shuffled_deck () -> Box<[Card; 52]>
{
    // https://stackoverflow.com/a/31361031
    let all_cards = unsafe
    {
        let mut _all_cards: [Card; 52] = mem::uninitialized();

        let mut ids_available: Vec<u8> = (0..52).collect();

        // https://stackoverflow.com/a/26035435
        let mut ids_avail_slice = ids_available.as_mut_slice();
        rand::thread_rng().shuffle(ids_avail_slice);
        let mut id_iter = ids_avail_slice.iter_mut();

        for color in Color::iterator()
        {
            for rank in Rank::iterator()
            {

                let curr_id = *(id_iter.next().unwrap());

                let card = Card
                {
                    color:     *color,
                    rank:      *rank,
                    id:        curr_id,
                    facing_up: false
                };

                _all_cards[curr_id as usize] = card;
            }
        }

        _all_cards
    };

    Box::new(all_cards)
}
<|endoftext|>


<commit_before>
use cpython::exc::{RuntimeError, IndexError};
use cpython::{py_class, PyErr, PyResult, PyInt, PyBytes, PyList, ToPyObject};
use cpython::{Python, PyObject};

use edgeql_parser::position::InflatedPos;

py_class!(pub class SourcePoint |py| {
    data _position: InflatedPos;
    @classmethod def from_offsets(cls, data: PyBytes, offsets: PyObject)
        -> PyResult<PyList>
    {
        let mut list: Vec<usize> = offsets.extract(py)?;
        let data: &[u8] = data.data(py);
        list.sort();
        let result = InflatedPos::from_offsets(data, &list)
            .map_err(|e| PyErr::new::<RuntimeError, _>(py, e.to_string()))?;
        Ok(result.into_iter()
            .map(|pos| SourcePoint::create_instance(py, pos))
            .collect::<Result<Vec<_>, _>>()?
            .to_py_object(py))
    }
    @property def line(&self) -> PyResult<PyInt> {
        Ok((self._position(py).line + 1).to_py_object(py))
    }
    @property def zero_based_line(&self) -> PyResult<PyInt> {
        Ok((self._position(py).line).to_py_object(py))
    }
    @property def column(&self) -> PyResult<PyInt> {
        Ok((self._position(py).column + 1).to_py_object(py))
    }
    @property def utf16column(&self) -> PyResult<PyInt> {
        Ok((self._position(py).utf16column).to_py_object(py))
    }
    @property def offset(&self) -> PyResult<PyInt> {
        Ok((self._position(py).offset).to_py_object(py))
    }
    @property def char_offset(&self) -> PyResult<PyInt> {
        Ok((self._position(py).char_offset).to_py_object(py))
    }
});

fn _offset_of_line(text: &str, target: usize) -> Option<usize> {
    let mut was_lf = false;
    let mut line = 0;  // this assumes line found by rfind
    for (idx, &byte) in text.as_bytes().iter().enumerate() {
        if line >= target {
            return Some(idx);
        }
        match byte {
            b'\n' => {
                line += 1;
                was_lf = false;
            }
            _ if was_lf => {
                line += 1;
                if line >= target {
                    return Some(idx);
                }
                was_lf = byte == b'\r';
            }
            b'\r' => {
                was_lf = true;
            }
            _ => {}
        }
    }
    if was_lf {
        line += 1;
    }
    if target > line {
        return None;
    }
    Some(text.len())
}

pub fn offset_of_line(py: Python, text: &str, target: usize) -> PyResult<usize>
{
    match _offset_of_line(text, target) {
        Some(offset) => Ok(offset),
        None => {
            Err(PyErr::new::<IndexError, _>(py, "line number is too large"))
        }
    }
}

#[test]
fn line_offsets() {
    assert_eq!(_offset_of_line("line1\nline2\nline3", 0), Some(0));
    assert_eq!(_offset_of_line("line1\nline2\nline3", 1), Some(6));
    assert_eq!(_offset_of_line("line1\nline2\nline3", 2), Some(12));
    assert_eq!(_offset_of_line("line1\nline2\nline3", 3), None);
    assert_eq!(_offset_of_line("line1\rline2\rline3", 0), Some(0));
    assert_eq!(_offset_of_line("line1\rline2\rline3", 1), Some(6));
    assert_eq!(_offset_of_line("line1\rline2\rline3", 2), Some(12));
    assert_eq!(_offset_of_line("line1\rline2\rline3", 3), None);
    assert_eq!(_offset_of_line("line1\r\nline2\r\nline3", 0), Some(0));
    assert_eq!(_offset_of_line("line1\r\nline2\r\nline3", 1), Some(7));
    assert_eq!(_offset_of_line("line1\r\nline2\r\nline3", 2), Some(14));
    assert_eq!(_offset_of_line("line1\r\nline2\r\nline3", 3), None);
    assert_eq!(_offset_of_line("line1\rline2\r\nline3\n", 0), Some(0));
    assert_eq!(_offset_of_line("line1\rline2\r\nline3\n", 1), Some(6));
    assert_eq!(_offset_of_line("line1\rline2\r\nline3\n", 2), Some(13));
    assert_eq!(_offset_of_line("line1\rline2\r\nline3\n", 3), Some(19));
    assert_eq!(_offset_of_line("line1\rline2\r\nline3\n", 4), None);
    assert_eq!(_offset_of_line("line1\nline2\rline3\r\n", 0), Some(0));
    assert_eq!(_offset_of_line("line1\nline2\rline3\r\n", 1), Some(6));
    assert_eq!(_offset_of_line("line1\nline2\rline3\r\n", 2), Some(12));
    assert_eq!(_offset_of_line("line1\nline2\rline3\r\n", 3), Some(19));
    assert_eq!(_offset_of_line("line1\nline2\rline3\r\n", 4), None);
    assert_eq!(_offset_of_line("line1\n\rline2\r\rline3\r", 0), Some(0));
    assert_eq!(_offset_of_line("line1\n\rline2\r\rline3\r", 1), Some(6));
    assert_eq!(_offset_of_line("line1\n\rline2\r\rline3\r", 2), Some(7));
    assert_eq!(_offset_of_line("line1\n\rline2\r\rline3\r", 3), Some(13));
    assert_eq!(_offset_of_line("line1\n\rline2\r\rline3\r", 4), Some(14));
    assert_eq!(_offset_of_line("line1\n\rline2\r\rline3\r", 5), Some(20));
    assert_eq!(_offset_of_line("line1\n\rline2\r\rline3\r", 6), None);
}
<commit_msg>Silence an unused argument warning in edgeql-rust (#2895)<commit_after>
use cpython::exc::{RuntimeError, IndexError};
use cpython::{py_class, PyErr, PyResult, PyInt, PyBytes, PyList, ToPyObject};
use cpython::{Python, PyObject};

use edgeql_parser::position::InflatedPos;

py_class!(pub class SourcePoint |py| {
    data _position: InflatedPos;
    @classmethod def from_offsets(_cls, data: PyBytes, offsets: PyObject)
        -> PyResult<PyList>
    {
        let mut list: Vec<usize> = offsets.extract(py)?;
        let data: &[u8] = data.data(py);
        list.sort();
        let result = InflatedPos::from_offsets(data, &list)
            .map_err(|e| PyErr::new::<RuntimeError, _>(py, e.to_string()))?;
        Ok(result.into_iter()
            .map(|pos| SourcePoint::create_instance(py, pos))
            .collect::<Result<Vec<_>, _>>()?
            .to_py_object(py))
    }
    @property def line(&self) -> PyResult<PyInt> {
        Ok((self._position(py).line + 1).to_py_object(py))
    }
    @property def zero_based_line(&self) -> PyResult<PyInt> {
        Ok((self._position(py).line).to_py_object(py))
    }
    @property def column(&self) -> PyResult<PyInt> {
        Ok((self._position(py).column + 1).to_py_object(py))
    }
    @property def utf16column(&self) -> PyResult<PyInt> {
        Ok((self._position(py).utf16column).to_py_object(py))
    }
    @property def offset(&self) -> PyResult<PyInt> {
        Ok((self._position(py).offset).to_py_object(py))
    }
    @property def char_offset(&self) -> PyResult<PyInt> {
        Ok((self._position(py).char_offset).to_py_object(py))
    }
});

fn _offset_of_line(text: &str, target: usize) -> Option<usize> {
    let mut was_lf = false;
    let mut line = 0;  // this assumes line found by rfind
    for (idx, &byte) in text.as_bytes().iter().enumerate() {
        if line >= target {
            return Some(idx);
        }
        match byte {
            b'\n' => {
                line += 1;
                was_lf = false;
            }
            _ if was_lf => {
                line += 1;
                if line >= target {
                    return Some(idx);
                }
                was_lf = byte == b'\r';
            }
            b'\r' => {
                was_lf = true;
            }
            _ => {}
        }
    }
    if was_lf {
        line += 1;
    }
    if target > line {
        return None;
    }
    Some(text.len())
}

pub fn offset_of_line(py: Python, text: &str, target: usize) -> PyResult<usize>
{
    match _offset_of_line(text, target) {
        Some(offset) => Ok(offset),
        None => {
            Err(PyErr::new::<IndexError, _>(py, "line number is too large"))
        }
    }
}

#[test]
fn line_offsets() {
    assert_eq!(_offset_of_line("line1\nline2\nline3", 0), Some(0));
    assert_eq!(_offset_of_line("line1\nline2\nline3", 1), Some(6));
    assert_eq!(_offset_of_line("line1\nline2\nline3", 2), Some(12));
    assert_eq!(_offset_of_line("line1\nline2\nline3", 3), None);
    assert_eq!(_offset_of_line("line1\rline2\rline3", 0), Some(0));
    assert_eq!(_offset_of_line("line1\rline2\rline3", 1), Some(6));
    assert_eq!(_offset_of_line("line1\rline2\rline3", 2), Some(12));
    assert_eq!(_offset_of_line("line1\rline2\rline3", 3), None);
    assert_eq!(_offset_of_line("line1\r\nline2\r\nline3", 0), Some(0));
    assert_eq!(_offset_of_line("line1\r\nline2\r\nline3", 1), Some(7));
    assert_eq!(_offset_of_line("line1\r\nline2\r\nline3", 2), Some(14));
    assert_eq!(_offset_of_line("line1\r\nline2\r\nline3", 3), None);
    assert_eq!(_offset_of_line("line1\rline2\r\nline3\n", 0), Some(0));
    assert_eq!(_offset_of_line("line1\rline2\r\nline3\n", 1), Some(6));
    assert_eq!(_offset_of_line("line1\rline2\r\nline3\n", 2), Some(13));
    assert_eq!(_offset_of_line("line1\rline2\r\nline3\n", 3), Some(19));
    assert_eq!(_offset_of_line("line1\rline2\r\nline3\n", 4), None);
    assert_eq!(_offset_of_line("line1\nline2\rline3\r\n", 0), Some(0));
    assert_eq!(_offset_of_line("line1\nline2\rline3\r\n", 1), Some(6));
    assert_eq!(_offset_of_line("line1\nline2\rline3\r\n", 2), Some(12));
    assert_eq!(_offset_of_line("line1\nline2\rline3\r\n", 3), Some(19));
    assert_eq!(_offset_of_line("line1\nline2\rline3\r\n", 4), None);
    assert_eq!(_offset_of_line("line1\n\rline2\r\rline3\r", 0), Some(0));
    assert_eq!(_offset_of_line("line1\n\rline2\r\rline3\r", 1), Some(6));
    assert_eq!(_offset_of_line("line1\n\rline2\r\rline3\r", 2), Some(7));
    assert_eq!(_offset_of_line("line1\n\rline2\r\rline3\r", 3), Some(13));
    assert_eq!(_offset_of_line("line1\n\rline2\r\rline3\r", 4), Some(14));
    assert_eq!(_offset_of_line("line1\n\rline2\r\rline3\r", 5), Some(20));
    assert_eq!(_offset_of_line("line1\n\rline2\r\rline3\r", 6), None);
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate log;
extern crate log4rs;

#[macro_use]
extern crate nickel;
use nickel::{Request, Response, MiddlewareResult, Nickel, MediaType};
use nickel::status::StatusCode;
use nickel::router::http_router::HttpRouter;

extern crate modifier;
use modifier::Modifier;

#[macro_use]
extern crate hyper;
use hyper::header::ContentLength;

use std::io::Read;

extern crate url;
use url::form_urlencoded;

extern crate webdriver;
use webdriver::response::{WebDriverResponse, ValueResponse};

use std::time;
use std::thread;

extern crate core;

extern crate rustc_serialize;

extern crate image;
use image::GenericImage;
use std::io::Cursor;

extern crate get_if_addrs;

extern crate plugin;
extern crate typemap;

mod chromedriver;
use chromedriver::{WebdriverRequestExtensions, WebdriverSession};

use core::ops::Deref;
extern crate rand;
extern crate regex;
#[macro_use]
extern crate lazy_static;

header! { (XExtra, "X-Extra") => [String] }

impl<'a, D> Modifier<Response<'a, D>> for XExtra {
    fn modify(self, res: &mut Response<'a, D>) {
        res.headers_mut().set(self)
    }
}

fn xpath_helper(session: &WebdriverSession, xpath: String) -> Result<ValueResponse, String> {
    match session.find_element_by_xpath(xpath) {
        Err(val) => Err(format!("Error while trying to get element: {:?}", val)),
        Ok(val) => {
            match val {
                WebDriverResponse::Generic(obj) => Ok(obj),
                _ => Err(format!("Didn't expect {:?}", val)),
            }
        }
    }
}

fn streams<'a, D>(request: &mut Request<D>, mut res: Response<'a, D>) -> MiddlewareResult<'a, D> {
    let mut buffer = String::new();
    request.origin.read_to_string(&mut buffer).unwrap();
    let mut parse = form_urlencoded::parse(buffer.as_bytes());
    let mut url = match parse.find(|k| k.0 == "url") {
        Some((_, value)) => value.into_owned(),
        None => return res.error(StatusCode::BadRequest, "No URL in request"),

    };
    let request_url = match url::Url::parse(&url) {
        Ok(value) => value,
        Err(_) => {
            return res.error(StatusCode::BadRequest,
                             format!("Request URL was dodgy: '{}'", url))
        }

    };
    let host = request_url.host_str().unwrap();
    let mut device_name: &str = "Laptop with HiDPI screen";
    let extra_fn: fn(WebdriverSession) -> String;
    let xpath = match host {
            "livestream.com" => {
                fn extra(session: WebdriverSession) -> String {
                    lazy_static! {
                        static ref RE: regex::Regex =
                            regex::Regex::new(
                                r"app-argument=http://livestream.com/accounts/(\d+)/events/(\d+)")
                        .unwrap();
                    }
                    let source = session.get_page_source();
                    let caps = RE.captures(&source).unwrap();
                    format!("[\"{}\",\"{}\"]", &caps[1], &caps[2])
                }
                extra_fn = extra;
                device_name = "Apple iPhone 5";
                "//div[@id='image-container']/img"
            }
            "www.ustream.tv" => {
                fn extra(session: WebdriverSession) -> String {
                    let res = xpath_helper(&session, "//video[@id='UViewer']".to_string());
                    match res {
                        Ok(val) => format!("\"{}\"", session.get_element_attribute(&val, "src")),
                        Err(val) => {
                            warn!("Error while trying to get Ustream extra data {}", val);
                            "".to_string()
                        }
                    }
                }
                extra_fn = extra;
                device_name = "Apple iPhone 5";
                "//video[@id='UViewer']"
            }
            "www.youtube.com" => {
                fn extra(_: WebdriverSession) -> String {
                    "".to_string()
                }
                extra_fn = extra;
                url = url + "?autoplay=1";
                "//div[@id='player']"
            }
            _ => {
                return res.error(StatusCode::BadRequest,
                                 format!("Request URL host ({}) wasn't in known list: '{}'",
                                         host,
                                         url))
            }

        }
        .to_string();
    let session = request.webdriver().deref().make_session(device_name);
    session.goto_url(url);
    thread::sleep(time::Duration::from_secs(5));
    let element: ValueResponse = match session.find_element_by_xpath(xpath) {
        Err(val) => {
            return res.error(StatusCode::BadRequest,
                             format!("Error while trying to get element: {:?}", val))
        }
        Ok(val) => {
            match val {
                WebDriverResponse::Generic(obj) => obj,
                _ => return res.error(StatusCode::BadRequest, format!("Didn't expect {:?}", val)),
            }
        }
    };
    let element_location = {
        let loc = session.get_element_location(&element);
        loc.unwrap()
            .find("value")
            .expect("value")
            .clone()
    };
    let element_size = {
        let size = session.get_element_size(&element);
        size.unwrap()
            .find("value")
            .expect("value")
            .clone()
    };
    let screenshot = {
        let png = session.get_screenshot_as_png();
        png.unwrap()
    };

    let cursor = Cursor::new(&screenshot);
    let mut loaded_image = image::load(cursor, image::ImageFormat::PNG).unwrap();
    let (width, height) = loaded_image.dimensions();
    debug!("Loaded image dimensions: {} x {}", width, height);
    let cropped = loaded_image.crop(
		element_location.find("x").expect("x").as_u64().expect("numeric x") as u32,
		element_location.find("y").expect("y").as_u64().expect("numeric y") as u32,
		element_size.find("width").expect("width").as_u64().expect("numeric width") as u32,
		element_size.find("height").expect("height").as_u64().expect("numeric height") as u32);

    let mut output_buffer: Vec<u8> = Vec::new();
    cropped.save(&mut output_buffer, image::ImageFormat::PNG).unwrap();

    let extra = extra_fn(session);
    res.set(XExtra(extra));

    res.set(MediaType::Png);
    res.set(ContentLength(output_buffer.len() as u64));
    res.send(output_buffer)
}

fn run(ip: std::net::IpAddr, port: u16, client: chromedriver::Webdriver) {
    let mut server = Nickel::new();
    server.utilize(chromedriver::WebdriverMiddleware::new(client));
    server.post("/streams", streams);
    server.listen((ip, port));
}

fn main() {
    log4rs::init_file("log.toml", Default::default()).unwrap();
    let port = 8000;
    let mut handles = Vec::new();
    for iface in get_if_addrs::get_if_addrs().unwrap() {
        handles.push(::std::thread::spawn(move || {
            let client = chromedriver::Webdriver::new();
            let ip = iface.ip();
            info!("Listening on {}:{} for {}", ip, port, iface.name);
            run(ip, port, client);
        }));
    }

    info!("All listeners spawned");

    for handle in handles {
        handle.join().unwrap();
    }
}
<commit_msg>Update XPath for Livestream<commit_after>#[macro_use]
extern crate log;
extern crate log4rs;

#[macro_use]
extern crate nickel;
use nickel::{Request, Response, MiddlewareResult, Nickel, MediaType};
use nickel::status::StatusCode;
use nickel::router::http_router::HttpRouter;

extern crate modifier;
use modifier::Modifier;

#[macro_use]
extern crate hyper;
use hyper::header::ContentLength;

use std::io::Read;

extern crate url;
use url::form_urlencoded;

extern crate webdriver;
use webdriver::response::{WebDriverResponse, ValueResponse};

use std::time;
use std::thread;

extern crate core;

extern crate rustc_serialize;

extern crate image;
use image::GenericImage;
use std::io::Cursor;

extern crate get_if_addrs;

extern crate plugin;
extern crate typemap;

mod chromedriver;
use chromedriver::{WebdriverRequestExtensions, WebdriverSession};

use core::ops::Deref;
extern crate rand;
extern crate regex;
#[macro_use]
extern crate lazy_static;

header! { (XExtra, "X-Extra") => [String] }

impl<'a, D> Modifier<Response<'a, D>> for XExtra {
    fn modify(self, res: &mut Response<'a, D>) {
        res.headers_mut().set(self)
    }
}

fn xpath_helper(session: &WebdriverSession, xpath: String) -> Result<ValueResponse, String> {
    match session.find_element_by_xpath(xpath) {
        Err(val) => Err(format!("Error while trying to get element: {:?}", val)),
        Ok(val) => {
            match val {
                WebDriverResponse::Generic(obj) => Ok(obj),
                _ => Err(format!("Didn't expect {:?}", val)),
            }
        }
    }
}

fn streams<'a, D>(request: &mut Request<D>, mut res: Response<'a, D>) -> MiddlewareResult<'a, D> {
    let mut buffer = String::new();
    request.origin.read_to_string(&mut buffer).unwrap();
    let mut parse = form_urlencoded::parse(buffer.as_bytes());
    let mut url = match parse.find(|k| k.0 == "url") {
        Some((_, value)) => value.into_owned(),
        None => return res.error(StatusCode::BadRequest, "No URL in request"),

    };
    let request_url = match url::Url::parse(&url) {
        Ok(value) => value,
        Err(_) => {
            return res.error(StatusCode::BadRequest,
                             format!("Request URL was dodgy: '{}'", url))
        }

    };
    let host = request_url.host_str().unwrap();
    let mut device_name: &str = "Laptop with HiDPI screen";
    let extra_fn: fn(WebdriverSession) -> String;
    let xpath = match host {
            "livestream.com" => {
                fn extra(session: WebdriverSession) -> String {
                    lazy_static! {
                        static ref RE: regex::Regex =
                            regex::Regex::new(
                                r"app-argument=http://livestream.com/accounts/(\d+)/events/(\d+)")
                        .unwrap();
                    }
                    let source = session.get_page_source();
                    let caps = RE.captures(&source).unwrap();
                    format!("[\"{}\",\"{}\"]", &caps[1], &caps[2])
                }
                extra_fn = extra;
                device_name = "Apple iPhone 5";
                "//img[@class='thumbnail_image']"
            }
            "www.ustream.tv" => {
                fn extra(session: WebdriverSession) -> String {
                    let res = xpath_helper(&session, "//video[@id='UViewer']".to_string());
                    match res {
                        Ok(val) => format!("\"{}\"", session.get_element_attribute(&val, "src")),
                        Err(val) => {
                            warn!("Error while trying to get Ustream extra data {}", val);
                            "".to_string()
                        }
                    }
                }
                extra_fn = extra;
                device_name = "Apple iPhone 5";
                "//video[@id='UViewer']"
            }
            "www.youtube.com" => {
                fn extra(_: WebdriverSession) -> String {
                    "".to_string()
                }
                extra_fn = extra;
                url = url + "?autoplay=1";
                "//div[@id='player']"
            }
            _ => {
                return res.error(StatusCode::BadRequest,
                                 format!("Request URL host ({}) wasn't in known list: '{}'",
                                         host,
                                         url))
            }

        }
        .to_string();
    let session = request.webdriver().deref().make_session(device_name);
    session.goto_url(url);
    thread::sleep(time::Duration::from_secs(5));
    let element: ValueResponse = match session.find_element_by_xpath(xpath) {
        Err(val) => {
            return res.error(StatusCode::BadRequest,
                             format!("Error while trying to get element: {:?}", val))
        }
        Ok(val) => {
            match val {
                WebDriverResponse::Generic(obj) => obj,
                _ => return res.error(StatusCode::BadRequest, format!("Didn't expect {:?}", val)),
            }
        }
    };
    let element_location = {
        let loc = session.get_element_location(&element);
        loc.unwrap()
            .find("value")
            .expect("value")
            .clone()
    };
    let element_size = {
        let size = session.get_element_size(&element);
        size.unwrap()
            .find("value")
            .expect("value")
            .clone()
    };
    let screenshot = {
        let png = session.get_screenshot_as_png();
        png.unwrap()
    };

    let cursor = Cursor::new(&screenshot);
    let mut loaded_image = image::load(cursor, image::ImageFormat::PNG).unwrap();
    let (width, height) = loaded_image.dimensions();
    debug!("Loaded image dimensions: {} x {}", width, height);
    let cropped = loaded_image.crop(
		element_location.find("x").expect("x").as_u64().expect("numeric x") as u32,
		element_location.find("y").expect("y").as_u64().expect("numeric y") as u32,
		element_size.find("width").expect("width").as_u64().expect("numeric width") as u32,
		element_size.find("height").expect("height").as_u64().expect("numeric height") as u32);

    let mut output_buffer: Vec<u8> = Vec::new();
    cropped.save(&mut output_buffer, image::ImageFormat::PNG).unwrap();

    let extra = extra_fn(session);
    res.set(XExtra(extra));

    res.set(MediaType::Png);
    res.set(ContentLength(output_buffer.len() as u64));
    res.send(output_buffer)
}

fn run(ip: std::net::IpAddr, port: u16, client: chromedriver::Webdriver) {
    let mut server = Nickel::new();
    server.utilize(chromedriver::WebdriverMiddleware::new(client));
    server.post("/streams", streams);
    server.listen((ip, port));
}

fn main() {
    log4rs::init_file("log.toml", Default::default()).unwrap();
    let port = 8000;
    let mut handles = Vec::new();
    for iface in get_if_addrs::get_if_addrs().unwrap() {
        handles.push(::std::thread::spawn(move || {
            let client = chromedriver::Webdriver::new();
            let ip = iface.ip();
            info!("Listening on {}:{} for {}", ip, port, iface.name);
            run(ip, port, client);
        }));
    }

    info!("All listeners spawned");

    for handle in handles {
        handle.join().unwrap();
    }
}
<|endoftext|>


<commit_before>use std::net::{TcpListener, TcpStream};
use std::thread;

use std::io::Write;
use std::io::Read;

fn handle_client(mut stream: TcpStream) {
	let mut buf;
	loop {
		buf = [0; 512];
		let _ = match stream.read(&mut buf) {
			Err(e) => panic!("Got an error: {}", e),
			Ok(m) => {
				if m == 0 {
					// We got an EOF
					break;
				}
				m
			},
		};

		match stream.write(&buf) {
			Err(_) => break,
			Ok(_) => continue,
		}
	}
}

fn main() {
	let listener = TcpListener::bind("127.0.0.1:4444").unwrap();

	for stream in listener.incoming() {
		match stream {
			Ok(stream) => {
				thread::spawn(move|| {
					handle_client(stream);
				});
			},
			Err(e) => { println!("failed: {}", e) },
		}
	}

	drop(listener);
}<commit_msg>Small tweak to re-use buffer<commit_after>use std::net::{TcpListener, TcpStream};
use std::thread;

use std::io::Write;
use std::io::Read;

fn handle_client(mut stream: TcpStream) {
	let mut buf = [0; 512];
	loop {
		let n = match stream.read(&mut buf) {
			Err(e) => panic!("Got an error: {}", e),
			Ok(m) => {
				if m == 0 {
					// We got an EOF
					break;
				}
				m
			},
		};

		match stream.write(&buf[0:n]) {
			Err(_) => break,
			Ok(_) => continue,
		}
	}
}

fn main() {
	let listener = TcpListener::bind("127.0.0.1:4444").unwrap();

	for stream in listener.incoming() {
		match stream {
			Ok(stream) => {
				thread::spawn(move|| {
					handle_client(stream);
				});
			},
			Err(e) => { println!("failed: {}", e) },
		}
	}

	drop(listener);
}<|endoftext|>


<commit_before>use std::f64;
use std::option::Option;
use rand::Rng;
use distribution::{Distribution, Univariate, Discrete};
use error::StatsError;
use result;

#[derive(Debug, Clone, PartialEq)]
pub struct DiscreteUniform {
    min: i64,
    max: i64
}

impl DiscreteUniform {
    pub fn new(min: i64, max: i64) -> result::Result<DiscreteUniform> {
        if max > min {
            return Err(StatsError::BadParams);
        }
        Ok(DiscreteUniform{
            min: min,
            max: max
        })
    }
}

impl Distribution for DiscreteUniform {
    fn sample<R: Rng>(&self, r: &mut R) -> f64 {
        r.gen_range(self.min, self.max + 1) as f64
    }
}

impl Univariate for DiscreteUniform {
     fn mean(&self) -> f64 {
        (self.min + self.max) as f64 / 2.0
    }

    fn variance(&self) -> f64 {
        let diff = (self.max - self.min) as f64;
        ((diff + 1.0) * (diff + 1.0) - 1.0) / 12.0
    }

    fn std_dev(&self) -> f64 {
        self.variance().sqrt()
    }

    fn entropy(&self) -> f64 {
        let diff = (self.max - self.min) as f64;
        (diff + 1.0).ln()
    }

    fn skewness(&self) -> f64 {
        0.0
    }

    fn median(&self) -> Option<f64> {
        Some((self.min + self.max) as f64 / 2.0)
    }

    fn cdf(&self, x: f64) -> result::Result<f64> {
        if x < self.min as f64 {
            return Ok(0.0);
        }
        if x >= self.max as f64 {
            return Ok(1.0);
        }
        let lower = self.min as f64;
        let upper = self.max as f64;
        let ans = (x.floor() - lower + 1.0) / (upper - lower + 1.0);
        if x > 1.0 {
            return Ok(1.0);
        }
        Ok(ans)
    }
}

impl Discrete for DiscreteUniform {
    fn mode(&self) -> i64 {
        ((self.min + self.max) as f64 / 2.0).floor() as i64
    }

    fn min(&self) -> i64 {
        self.min
    }

    fn max(&self) -> i64 {
        self.max
    }

    fn pmf(&self, x: i64) -> f64 {
        if x >= self.min && x <= self.max {
            return 1.0 / (self.max - self.min + 1) as f64
        }
        0.0
    }

    fn ln_pmf(&self, x: i64) -> f64 {
        if x >= self.min && x <= self.max {
            return -((self.max - self.min + 1) as f64).ln()
        }
        f64::NEG_INFINITY
    }
}<commit_msg>implement discrete uniform tests<commit_after>use std::f64;
use std::option::Option;
use rand::Rng;
use distribution::{Distribution, Univariate, Discrete};
use error::StatsError;
use result;

#[derive(Debug, Clone, PartialEq)]
pub struct DiscreteUniform {
    min: i64,
    max: i64
}

impl DiscreteUniform {
    pub fn new(min: i64, max: i64) -> result::Result<DiscreteUniform> {
        if max < min {
            return Err(StatsError::BadParams);
        }
        Ok(DiscreteUniform{
            min: min,
            max: max
        })
    }
}

impl Distribution for DiscreteUniform {
    fn sample<R: Rng>(&self, r: &mut R) -> f64 {
        r.gen_range(self.min, self.max + 1) as f64
    }
}

impl Univariate for DiscreteUniform {
     fn mean(&self) -> f64 {
        (self.min + self.max) as f64 / 2.0
    }

    fn variance(&self) -> f64 {
        let diff = (self.max - self.min) as f64;
        ((diff + 1.0) * (diff + 1.0) - 1.0) / 12.0
    }

    fn std_dev(&self) -> f64 {
        self.variance().sqrt()
    }

    fn entropy(&self) -> f64 {
        let diff = (self.max - self.min) as f64;
        (diff + 1.0).ln()
    }

    fn skewness(&self) -> f64 {
        0.0
    }

    fn median(&self) -> Option<f64> {
        Some((self.min + self.max) as f64 / 2.0)
    }

    fn cdf(&self, x: f64) -> result::Result<f64> {
        if x < self.min as f64 {
            return Ok(0.0);
        }
        if x >= self.max as f64 {
            return Ok(1.0);
        }
        let lower = self.min as f64;
        let upper = self.max as f64;
        let ans = (x.floor() - lower + 1.0) / (upper - lower + 1.0);
        if x > 1.0 {
            return Ok(1.0);
        }
        Ok(ans)
    }
}

impl Discrete for DiscreteUniform {
    fn mode(&self) -> i64 {
        ((self.min + self.max) as f64 / 2.0).floor() as i64
    }

    fn min(&self) -> i64 {
        self.min
    }

    fn max(&self) -> i64 {
        self.max
    }

    fn pmf(&self, x: i64) -> f64 {
        if x >= self.min && x <= self.max {
            return 1.0 / (self.max - self.min + 1) as f64
        }
        0.0
    }

    fn ln_pmf(&self, x: i64) -> f64 {
        if x >= self.min && x <= self.max {
            return -((self.max - self.min + 1) as f64).ln()
        }
        f64::NEG_INFINITY
    }
}

#[cfg(test)]
mod test {
    use std::cmp::PartialEq;
    use std::fmt::Debug;
    use std::f64;
    use std::option::Option;
    use distribution::{Univariate, Discrete};
    use result;
    use super::DiscreteUniform;

    fn try_create(min: i64, max: i64) -> DiscreteUniform {
        let n = DiscreteUniform::new(min, max);
        assert!(n.is_ok());
        n.unwrap()
    }

    fn create_case(min: i64, max: i64) {
        let n = try_create(min, max);
        assert_eq!(min, n.min());
        assert_eq!(max, n.max());
    }

    fn bad_create_case(min: i64, max: i64) {
        let n = DiscreteUniform::new(min, max);
        assert!(n.is_err());
    }

    fn test_case<T, F>(min: i64, max: i64, expected: T, eval: F) where
        T : PartialEq + Debug,
        F : Fn(DiscreteUniform) -> T {

        let n = try_create(min, max);
        let x = eval(n);
        assert_eq!(expected, x);
    }

    fn test_option<F>(min: i64, max: i64, expected: f64, eval: F)
        where F : Fn(DiscreteUniform) -> Option<f64> {

        let n = try_create(min, max);
        let x = eval(n);
        assert!(x.is_some());

        let v = x.unwrap();
        assert_eq!(expected, v);
    }

    fn test_result<F>(min: i64, max: i64, expected: f64, eval: F)
        where F : Fn(DiscreteUniform) -> result::Result<f64> {

        let n = try_create(min, max);
        let x = eval(n);
        assert!(x.is_ok());

        let v = x.unwrap();
        assert_eq!(expected, v);
    }

    #[test]
    fn test_create() {
        create_case(-10, 10);
        create_case(0, 4);
        create_case(10, 20);
        create_case(20, 20);
    }

    #[test]
    fn test_bad_create() {
        bad_create_case(-1, -2);
        bad_create_case(6, 5);
    }

    #[test]
    fn test_mean() {
        test_case(-10, 10, 0.0, |x| x.mean());
        test_case(0, 4, 2.0, |x| x.mean());
        test_case(10, 20, 15.0, |x| x.mean());
        test_case(20, 20, 20.0, |x| x.mean());
    }

    #[test]
    fn test_variance() {
        test_case(-10, 10, 36.66666666666666666667, |x| x.variance());
        test_case(0, 4, 2.0, |x| x.variance());
        test_case(10, 20, 10.0, |x| x.variance());
        test_case(20, 20, 0.0, |x| x.variance());
    }

    #[test]
    fn test_std_dev() {
        test_case(-10, 10, (36.66666666666666666667f64).sqrt(), |x| x.std_dev());
        test_case(0, 4, (2.0f64).sqrt(), |x| x.std_dev());
        test_case(10, 20, (10.0f64).sqrt(), |x| x.std_dev());
        test_case(20, 20, 0.0, |x| x.std_dev());
    }

    #[test]
    fn test_entropy() {
        test_case(-10, 10, 3.0445224377234229965005979803657054342845752874046093, |x| x.entropy());
        test_case(0, 4, 1.6094379124341003746007593332261876395256013542685181, |x| x.entropy());
        test_case(10, 20, 2.3978952727983705440619435779651292998217068539374197, |x| x.entropy());
        test_case(20, 20, 0.0, |x| x.entropy());
    }

    #[test]
    fn test_skewness() {
        test_case(-10, 10, 0.0, |x| x.skewness());
        test_case(0, 4, 0.0, |x| x.skewness());
        test_case(10, 20, 0.0, |x| x.skewness());
        test_case(20, 20, 0.0, |x| x.skewness());
    }

    #[test]
    fn test_median() {
        test_option(-10, 10, 0.0, |x| x.median());
        test_option(0, 4, 2.0, |x| x.median());
        test_option(10, 20, 15.0, |x| x.median());
        test_option(20, 20, 20.0, |x| x.median());
    }

    #[test]
    fn test_mode() {
        test_case(-10, 10, 0, |x| x.mode());
        test_case(0, 4, 2, |x| x.mode());
        test_case(10, 20, 15, |x| x.mode());
        test_case(20, 20, 20, |x| x.mode());
    }

    #[test]
    fn test_pmf() {
        test_case(-10, 10, 0.04761904761904761904762, |x| x.pmf(-5));
        test_case(-10, 10, 0.04761904761904761904762, |x| x.pmf(1));
        test_case(-10, 10, 0.04761904761904761904762, |x| x.pmf(10));
        test_case(-10, -10, 0.0, |x| x.pmf(0));
        test_case(-10, -10, 1.0, |x| x.pmf(-10));
    }

    #[test]
    fn test_ln_pmf() {
        test_case(-10, 10, -3.0445224377234229965005979803657054342845752874046093, |x| x.ln_pmf(-5));
        test_case(-10, 10, -3.0445224377234229965005979803657054342845752874046093, |x| x.ln_pmf(1));
        test_case(-10, 10, -3.0445224377234229965005979803657054342845752874046093, |x| x.ln_pmf(10));
        test_case(-10, -10, f64::NEG_INFINITY, |x| x.ln_pmf(0));
        test_case(-10, -10, 0.0, |x| x.ln_pmf(-10));
    }

    #[test]
    fn test_cdf() {
        test_result(-10, 10, 0.2857142857142857142857, |x| x.cdf(-5.0));
        test_result(-10, 10, 0.5714285714285714285714, |x| x.cdf(1.0));
        test_result(-10, 10, 1.0, |x| x.cdf(10.0));
        test_result(-10, -10, 1.0, |x| x.cdf(0.0));
        test_result(-10, -10, 1.0, |x| x.cdf(-10.0));
        test_result(-10, -10, 0.0, |x| x.cdf(-11.0));
    }
}<|endoftext|>


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

#[macro_use]
extern crate enum_map;
#[macro_use]
extern crate serde;
extern crate serde_json;
extern crate serde_test;

use serde_test::{assert_tokens, Token};

#[derive(Debug, EnumMap, Deserialize, Serialize)]
enum Example {
    A,
    B,
}

#[test]
fn serialization() {
    let map = enum_map! { Example::A => 5, Example::B => 10 };
    assert_tokens(
        &map,
        &[
            Token::Map { len: Some(2) },
            Token::UnitVariant {
                name: "Example",
                variant: "A",
            },
            Token::I32(5),
            Token::UnitVariant {
                name: "Example",
                variant: "B",
            },
            Token::I32(10),
            Token::MapEnd,
        ],
    );
}

const JSON: &str = r#"{"A":5,"B":10}"#;

#[test]
fn json_serialization() {
    let map = enum_map! { Example::A => 5, Example::B => 10 };
    assert_eq!(serde_json::to_string(&map).unwrap(), String::from(JSON));
}

#[test]
fn json_deserialization() {
    let example: EnumMap<Example, i32> = serde_json::from_str(JSON).unwrap();
    assert_eq!(example, enum_map! { Example::A => 5, Example::B => 10 });
}

#[test]
fn json_invalid_deserialization() {
    let example: Result<EnumMap<Example, i32>, _> = serde_json::from_str(r"{}");
    assert!(example.is_err());
}

#[test]
fn json_invalid_key() {
    let example: Result<EnumMap<Example, i32>, _> =
        serde_json::from_str(r#"{"a": 5, "b": 10, "c": 6}"#);
    assert!(example.is_err());
}
<commit_msg>Use EnumMap in serde tests<commit_after>#![no_std]
#![cfg(feature = "serde")]

#[macro_use]
extern crate enum_map;
#[macro_use]
extern crate serde;
extern crate serde_json;
extern crate serde_test;

use enum_map::EnumMap;

use serde_test::{assert_tokens, Token};

#[derive(Debug, EnumMap, Deserialize, Serialize)]
enum Example {
    A,
    B,
}

#[test]
fn serialization() {
    let map = enum_map! { Example::A => 5, Example::B => 10 };
    assert_tokens(
        &map,
        &[
            Token::Map { len: Some(2) },
            Token::UnitVariant {
                name: "Example",
                variant: "A",
            },
            Token::I32(5),
            Token::UnitVariant {
                name: "Example",
                variant: "B",
            },
            Token::I32(10),
            Token::MapEnd,
        ],
    );
}

const JSON: &str = r#"{"A":5,"B":10}"#;

#[test]
fn json_serialization() {
    let map = enum_map! { Example::A => 5, Example::B => 10 };
    assert_eq!(serde_json::to_string(&map).unwrap(), String::from(JSON));
}

#[test]
fn json_deserialization() {
    let example: EnumMap<Example, i32> = serde_json::from_str(JSON).unwrap();
    assert_eq!(example, enum_map! { Example::A => 5, Example::B => 10 });
}

#[test]
fn json_invalid_deserialization() {
    let example: Result<EnumMap<Example, i32>, _> = serde_json::from_str(r"{}");
    assert!(example.is_err());
}

#[test]
fn json_invalid_key() {
    let example: Result<EnumMap<Example, i32>, _> =
        serde_json::from_str(r#"{"a": 5, "b": 10, "c": 6}"#);
    assert!(example.is_err());
}
<|endoftext|>


<commit_before>use std::mem;

/// Lots of thanks to reem and Sharp for help with this from the #rust channel

#[derive(Show,PartialEq)]
struct Node<T> {
    pub payload: T,
    next: Option<Box<Node<T>>>,
    prev: Option<Box<Node<T>>>,
}

impl<T> Node<T> {
    pub fn new(payload: T) -> Node<T> {
        Node::<T> {
            payload: payload,
            next: None,
            prev: None,
        }
    }

    pub fn payload(&self) -> Option<&T> {
        Some(&self.payload)
    }

    pub fn insert_after(&mut self, mut new: Box<Node<T>>) -> Option<Box<Node<T>>> {
        mem::swap(&mut new.next, &mut self.next);
        mem::replace(&mut self.next, Some(new))
    }

    pub fn insert_before(&mut self, mut new: Box<Node<T>>) -> Option<Box<Node<T>>> {
        mem::swap(&mut new.prev, &mut self.prev);
        mem::replace(&mut self.prev, Some(new))
    }

    pub fn next(&mut self) -> Option<&mut T> {
        let Node {
            ref mut payload,
            ref mut prev,
            ref mut next,
        } = *self;

        match *next {
            Some(ref mut next) => {
                mem::swap(&mut next.payload, payload);

                let mut next = &mut **next;     // Cannot completely understand this bit yet.
                mem::swap(&mut next.next, &mut next.prev);

                mem::swap(&mut next.prev, prev);
            },
            None    => return None,
        }
        mem::swap(prev, next);
        Some(payload)
    }
}

pub struct LinkedList<T> {
    head: Option<Box<Node<T>>>,
    tail: Option<Box<Node<T>>>,
}

impl<T> LinkedList<T> {
    pub fn new() -> LinkedList<T> {
        LinkedList::<T> {
            head: None,
            tail: None,
        }
    }
}

#[test]
fn node_new() {
    let expected = Node {
        payload: "test",
        next: None,
        prev: None,
    };

    let node: Node<&str> = Node::new("test");

    assert_eq!(expected.payload,  node.payload);
    assert_eq!(expected.next,     node.next);
    assert_eq!(expected.prev,     node.prev);
}

#[test]
fn node_payload() {
    let node: Node<&str> = Node::new("test");
    assert_eq!(&"test", node.payload().unwrap());
}

#[test]
fn node_insert_after() {
    let mut node: Node<&str> = Node::new("one");
    node.insert_after(Box::new(Node::new("two")));
    assert_eq!("two", node.next.unwrap().payload);

}

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

}
<commit_msg>Test for insert_before<commit_after>use std::mem;

/// Lots of thanks to reem and Sharp for help with this from the #rust channel

#[derive(Debug,PartialEq)]
struct Node<T> {
    pub payload: T,
    next: Option<Box<Node<T>>>,
    prev: Option<Box<Node<T>>>,
}

impl<T> Node<T> {
    pub fn new(payload: T) -> Node<T> {
        Node::<T> {
            payload: payload,
            next: None,
            prev: None,
        }
    }

    pub fn payload(&self) -> Option<&T> {
        Some(&self.payload)
    }

    pub fn insert_after(&mut self, mut new: Box<Node<T>>) -> Option<Box<Node<T>>> {
        mem::swap(&mut new.next, &mut self.next);
        mem::replace(&mut self.next, Some(new))
    }

    pub fn insert_before(&mut self, mut new: Box<Node<T>>) -> Option<Box<Node<T>>> {
        mem::swap(&mut new.prev, &mut self.prev);
        mem::replace(&mut self.prev, Some(new))
    }

    pub fn next(&mut self) -> Option<&mut T> {
        let Node {
            ref mut payload,
            ref mut prev,
            ref mut next,
        } = *self;

        match *next {
            Some(ref mut next) => {
                mem::swap(&mut next.payload, payload);

                let mut next = &mut **next;     // Cannot completely understand this bit yet.
                mem::swap(&mut next.next, &mut next.prev);

                mem::swap(&mut next.prev, prev);
            },
            None    => return None,
        }
        mem::swap(prev, next);
        Some(payload)
    }
}

pub struct LinkedList<T> {
    head: Option<Box<Node<T>>>,
    tail: Option<Box<Node<T>>>,
}

impl<T> LinkedList<T> {
    pub fn new() -> LinkedList<T> {
        LinkedList::<T> {
            head: None,
            tail: None,
        }
    }
}

#[test]
fn node_new() {
    let expected = Node {
        payload: "test",
        next: None,
        prev: None,
    };

    let node: Node<&str> = Node::new("test");

    assert_eq!(expected.payload,  node.payload);
    assert_eq!(expected.next,     node.next);
    assert_eq!(expected.prev,     node.prev);
}

#[test]
fn node_payload() {
    let node: Node<&str> = Node::new("test");
    assert_eq!(&"test", node.payload().unwrap());
}

#[test]
fn node_insert_after() {
    let mut node: Node<&str> = Node::new("one");
    node.insert_after(Box::new(Node::new("two")));
    assert_eq!("two", node.next.unwrap().payload);

}

#[test]
fn node_insert_before() {
    let mut node: Node<&str> = Node::new("two");
    node.insert_before(Box::new(Node::new("one")));
    assert_eq!("one", node.prev.unwrap().payload);
}

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

}
<|endoftext|>


<commit_before>//! Handle network connections for a varlink service

#![allow(dead_code)]

use libc::{close, dup2, getpid};
use std::env;
use std::io::{Read, Write};
use std::net::{Shutdown, TcpStream};
use std::os::unix::io::{FromRawFd, IntoRawFd};
use std::os::unix::net::UnixStream;
use std::os::unix::process::CommandExt;
use std::process::{Child, Command};
use tempfile::tempdir;
use tempfile::TempDir;
// FIXME: abstract unix domains sockets still not in std
// FIXME: https://github.com/rust-lang/rust/issues/14194
use unix_socket::UnixStream as AbstractStream;
use {ErrorKind, Result};

pub enum VarlinkStream {
    TCP(TcpStream),
    UNIX(UnixStream),
}

pub fn varlink_exec<S: ?Sized + AsRef<str>>(
    address: &S,
) -> Result<(Child, String, Option<TempDir>)> {
    let executable = address.as_ref();
    use unix_socket::UnixListener;

    let dir = tempdir()?;
    let file_path = dir.path().join("varlink-socket");

    let listener = UnixListener::bind(file_path.clone())?;
    let fd = listener.into_raw_fd();

    let child = Command::new("sh")
        .arg("-c")
        .arg(executable)
        .before_exec({
            let file_path = file_path.clone();
            move || {
                unsafe {
                    if fd != 3 {
                        close(3);
                        dup2(fd, 3);
                    }
                    env::set_var("VARLINK_ADDRESS", format!("unix:{}", file_path.display()));
                    env::set_var("LISTEN_FDS", "1");
                    env::set_var("LISTEN_FDNAMES", "varlink");
                    env::set_var("LISTEN_PID", format!("{}", getpid()));
                }
                Ok(())
            }
        })
        .spawn()?;
    Ok((child, format!("unix:{}", file_path.display()), Some(dir)))
}

pub fn varlink_bridge<S: ?Sized + AsRef<str>>(address: &S) -> Result<(Child, VarlinkStream)> {
    let executable = address.as_ref();
    //use unix_socket::UnixStream;
    let (stream0, stream1) = UnixStream::pair()?;
    let fd = stream1.into_raw_fd();
    let childin = unsafe { ::std::fs::File::from_raw_fd(fd) };
    let childout = unsafe { ::std::fs::File::from_raw_fd(fd) };

    let child = Command::new("sh")
        .arg("-c")
        .arg(executable)
        .stdin(childin)
        .stdout(childout)
        .spawn()?;
    Ok((child, VarlinkStream::UNIX(stream0)))
}

impl<'a> VarlinkStream {
    pub fn connect<S: ?Sized + AsRef<str>>(address: &S) -> Result<(Self, String)> {
        let address = address.as_ref();
        let new_address: String = address.into();

        if new_address.starts_with("tcp:") {
            Ok((
                VarlinkStream::TCP(TcpStream::connect(&new_address[4..])?),
                new_address,
            ))
        } else if new_address.starts_with("unix:") {
            let mut addr = String::from(new_address[5..].split(';').next().unwrap());
            if addr.starts_with('@') {
                addr = addr.replacen('@', "\0", 1);
                let l = AbstractStream::connect(addr)?;
                unsafe {
                    return Ok((
                        VarlinkStream::UNIX(UnixStream::from_raw_fd(l.into_raw_fd())),
                        new_address,
                    ));
                }
            }
            Ok((VarlinkStream::UNIX(UnixStream::connect(addr)?), new_address))
        } else {
            Err(ErrorKind::InvalidAddress)?
        }
    }

    pub fn split(&mut self) -> Result<(Box<Read + Send + Sync>, Box<Write + Send + Sync>)> {
        match *self {
            VarlinkStream::TCP(ref mut s) => {
                Ok((Box::new(s.try_clone()?), Box::new(s.try_clone()?)))
            }
            VarlinkStream::UNIX(ref mut s) => {
                Ok((Box::new(s.try_clone()?), Box::new(s.try_clone()?)))
            }
        }
    }

    pub fn shutdown(&mut self) -> Result<()> {
        match *self {
            VarlinkStream::TCP(ref mut s) => s.shutdown(Shutdown::Both)?,
            VarlinkStream::UNIX(ref mut s) => s.shutdown(Shutdown::Both)?,
        }
        Ok(())
    }

    pub fn set_nonblocking(&self, b: bool) -> Result<()> {
        match *self {
            VarlinkStream::TCP(ref l) => l.set_nonblocking(b)?,
            VarlinkStream::UNIX(ref l) => l.set_nonblocking(b)?,
        }
        Ok(())
    }
}

impl Drop for VarlinkStream {
    fn drop(&mut self) {
        let _r = self.shutdown();
    }
}
<commit_msg>varlink_exec: use "sh -c 'exec <command>'"<commit_after>//! Handle network connections for a varlink service

#![allow(dead_code)]

use libc::{close, dup2, getpid};
use std::env;
use std::io::{Read, Write};
use std::net::{Shutdown, TcpStream};
use std::os::unix::io::{FromRawFd, IntoRawFd};
use std::os::unix::net::UnixStream;
use std::os::unix::process::CommandExt;
use std::process::{Child, Command};
use tempfile::tempdir;
use tempfile::TempDir;
// FIXME: abstract unix domains sockets still not in std
// FIXME: https://github.com/rust-lang/rust/issues/14194
use unix_socket::UnixStream as AbstractStream;
use {ErrorKind, Result};

pub enum VarlinkStream {
    TCP(TcpStream),
    UNIX(UnixStream),
}

pub fn varlink_exec<S: ?Sized + AsRef<str>>(
    address: &S,
) -> Result<(Child, String, Option<TempDir>)> {
    let executable = String::from("exec ") + address.as_ref();
    use unix_socket::UnixListener;

    let dir = tempdir()?;
    let file_path = dir.path().join("varlink-socket");

    let listener = UnixListener::bind(file_path.clone())?;
    let fd = listener.into_raw_fd();

    let child = Command::new("sh")
        .arg("-c")
        .arg(executable)
        .before_exec({
            let file_path = file_path.clone();
            move || {
                unsafe {
                    if fd != 3 {
                        close(3);
                        dup2(fd, 3);
                    }
                    env::set_var("VARLINK_ADDRESS", format!("unix:{}", file_path.display()));
                    env::set_var("LISTEN_FDS", "1");
                    env::set_var("LISTEN_FDNAMES", "varlink");
                    env::set_var("LISTEN_PID", format!("{}", getpid()));
                }
                Ok(())
            }
        })
        .spawn()?;
    Ok((child, format!("unix:{}", file_path.display()), Some(dir)))
}

pub fn varlink_bridge<S: ?Sized + AsRef<str>>(address: &S) -> Result<(Child, VarlinkStream)> {
    let executable = address.as_ref();
    //use unix_socket::UnixStream;
    let (stream0, stream1) = UnixStream::pair()?;
    let fd = stream1.into_raw_fd();
    let childin = unsafe { ::std::fs::File::from_raw_fd(fd) };
    let childout = unsafe { ::std::fs::File::from_raw_fd(fd) };

    let child = Command::new("sh")
        .arg("-c")
        .arg(executable)
        .stdin(childin)
        .stdout(childout)
        .spawn()?;
    Ok((child, VarlinkStream::UNIX(stream0)))
}

impl<'a> VarlinkStream {
    pub fn connect<S: ?Sized + AsRef<str>>(address: &S) -> Result<(Self, String)> {
        let address = address.as_ref();
        let new_address: String = address.into();

        if new_address.starts_with("tcp:") {
            Ok((
                VarlinkStream::TCP(TcpStream::connect(&new_address[4..])?),
                new_address,
            ))
        } else if new_address.starts_with("unix:") {
            let mut addr = String::from(new_address[5..].split(';').next().unwrap());
            if addr.starts_with('@') {
                addr = addr.replacen('@', "\0", 1);
                let l = AbstractStream::connect(addr)?;
                unsafe {
                    return Ok((
                        VarlinkStream::UNIX(UnixStream::from_raw_fd(l.into_raw_fd())),
                        new_address,
                    ));
                }
            }
            Ok((VarlinkStream::UNIX(UnixStream::connect(addr)?), new_address))
        } else {
            Err(ErrorKind::InvalidAddress)?
        }
    }

    pub fn split(&mut self) -> Result<(Box<Read + Send + Sync>, Box<Write + Send + Sync>)> {
        match *self {
            VarlinkStream::TCP(ref mut s) => {
                Ok((Box::new(s.try_clone()?), Box::new(s.try_clone()?)))
            }
            VarlinkStream::UNIX(ref mut s) => {
                Ok((Box::new(s.try_clone()?), Box::new(s.try_clone()?)))
            }
        }
    }

    pub fn shutdown(&mut self) -> Result<()> {
        match *self {
            VarlinkStream::TCP(ref mut s) => s.shutdown(Shutdown::Both)?,
            VarlinkStream::UNIX(ref mut s) => s.shutdown(Shutdown::Both)?,
        }
        Ok(())
    }

    pub fn set_nonblocking(&self, b: bool) -> Result<()> {
        match *self {
            VarlinkStream::TCP(ref l) => l.set_nonblocking(b)?,
            VarlinkStream::UNIX(ref l) => l.set_nonblocking(b)?,
        }
        Ok(())
    }
}

impl Drop for VarlinkStream {
    fn drop(&mut self) {
        let _r = self.shutdown();
    }
}
<|endoftext|>


<commit_before>// `F` must implement `Fn` for a closure which takes no
// inputs and returns nothing - exactly what is required
// for `print`.
fn apply<F>(f: F) where
    F: Fn() {
    f()
}

fn main() {
    let x = 7;

    // Capture `x` into an anonymous type and implement
    // `Fn` for it. Store it in `print`.
    let print = || println!("{}", x);

    apply(print);
}
<commit_msg>Explicit return unit type<commit_after>// `F` must implement `Fn` for a closure which takes no
// inputs and returns nothing - exactly what is required
// for `print`.
fn apply<F>(f: F) where
    F: Fn() {
    f();
}

fn main() {
    let x = 7;

    // Capture `x` into an anonymous type and implement
    // `Fn` for it. Store it in `print`.
    let print = || println!("{}", x);

    apply(print);
}
<|endoftext|>


<commit_before>//
// Copyright 2018 The Project Oak Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#[macro_use]
extern crate log;
extern crate oak;
extern crate oak_derive;
extern crate oak_log;
extern crate protobuf;

mod proto;

use oak::{GrpcResult, OakNode, ResponseWriter};
use oak_derive::OakExports;
use proto::hello_world::{HelloRequest, HelloResponse};
use proto::hello_world_grpc::{dispatch, HelloWorldNode};
use protobuf::ProtobufEnum;

#[derive(OakExports)]
struct Node;

impl oak::OakNode for Node {
    fn new() -> Self {
        oak_log::init(log::Level::Debug).unwrap();
        Node
    }
    fn invoke(&mut self, method: &str, req: &[u8], out: &mut oak::SendChannelHalf) {
        dispatch(self, method, req, out)
    }
}

impl HelloWorldNode for Node {
    fn say_hello(&mut self, req: HelloRequest) -> GrpcResult<HelloResponse> {
        if req.greeting == "Query-of-Error" {
            let mut status = oak::proto::status::Status::new();
            status.set_code(3); // INVALID_ARGUMENT
            status.set_message("Deliberate error (code 3)".to_string());
            return Err(status);
        }
        info!("Say hello to {}", req.greeting);
        let mut res = HelloResponse::new();
        res.reply = format!("HELLO {}!", req.greeting);
        Ok(res)
    }

    fn lots_of_replies(
        &mut self,
        req: HelloRequest,
        writer: &mut dyn ResponseWriter<HelloResponse>,
    ) -> GrpcResult<()> {
        info!("Say hello to {}", req.greeting);
        let mut res1 = HelloResponse::new();
        res1.reply = format!("HELLO {}!", req.greeting);
        writer.write(res1);
        info!("Say bonjour to {}", req.greeting);
        let mut res2 = HelloResponse::new();
        res2.reply = format!("BONJOUR {}!", req.greeting);
        writer.write(res2);
        Ok(())
    }

    fn lots_of_greetings(&mut self, reqs: Vec<HelloRequest>) -> GrpcResult<HelloResponse> {
        info!("Say hello");
        let mut msg = String::new();
        msg.push_str("Hello ");
        msg.push_str(&recipients(&reqs));
        let mut res = HelloResponse::new();
        res.reply = msg;
        Ok(res)
    }

    fn bidi_hello(
        &mut self,
        reqs: Vec<HelloRequest>,
        writer: &mut dyn ResponseWriter<HelloResponse>,
    ) -> GrpcResult<()> {
        info!("Say hello");
        let msg = recipients(&reqs);
        let mut res1 = HelloResponse::new();
        res1.reply = format!("HELLO {}!", msg);
        writer.write(res1);
        let mut res2 = HelloResponse::new();
        res2.reply = format!("BONJOUR {}!", msg);
        writer.write(res2);
        Ok(())
    }
}

fn recipients(reqs: &[HelloRequest]) -> String {
    let mut result = String::new();
    for (i, req) in reqs.iter().enumerate() {
        if i > 0 {
            result.push_str(", ");
        }
        result.push_str(&req.greeting);
    }
    result
}
<commit_msg>Make hello_world example use storage<commit_after>//
// Copyright 2018 The Project Oak Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#[macro_use]
extern crate log;
extern crate oak;
extern crate oak_derive;
extern crate oak_log;
extern crate protobuf;

mod proto;

use oak::{GrpcResult, OakNode, ResponseWriter};
use oak_derive::OakExports;
use proto::hello_world::{HelloRequest, HelloResponse};
use proto::hello_world_grpc::{dispatch, HelloWorldNode};
use protobuf::ProtobufEnum;

#[derive(OakExports)]
struct Node;

const STORAGE_NAME: &[u8] = b"HelloWorld";
const FIELD_NAME: &[u8] = b"last-greeting";

impl oak::OakNode for Node {
    fn new() -> Self {
        oak_log::init(log::Level::Debug).unwrap();
        Node
    }
    fn invoke(&mut self, method: &str, req: &[u8], out: &mut oak::SendChannelHalf) {
        dispatch(self, method, req, out)
    }
}

impl HelloWorldNode for Node {
    fn say_hello(&mut self, req: HelloRequest) -> GrpcResult<HelloResponse> {
        if req.greeting == "Query-of-Error" {
            let mut status = oak::proto::status::Status::new();
            status.set_code(3); // INVALID_ARGUMENT
            status.set_message("Deliberate error (code 3)".to_string());
            return Err(status);
        }
        // Save the latest greeting to storage.
        oak::storage::write(STORAGE_NAME, FIELD_NAME, req.greeting.as_bytes());
        info!("Say hello to {}", req.greeting);
        let mut res = HelloResponse::new();
        res.reply = format!("HELLO {}!", req.greeting);
        Ok(res)
    }

    fn lots_of_replies(
        &mut self,
        req: HelloRequest,
        writer: &mut dyn ResponseWriter<HelloResponse>,
    ) -> GrpcResult<()> {
        info!("Say hello to {}", req.greeting);
        let mut res1 = HelloResponse::new();
        res1.reply = format!("HELLO {}!", req.greeting);
        writer.write(res1);

        // Also generate a response with the last-stored value.
        let prev_bytes = oak::storage::read(STORAGE_NAME, FIELD_NAME);
        let previous = std::str::from_utf8(&prev_bytes).unwrap();
        info!("Say bonjour to {}", previous);
        let mut res2 = HelloResponse::new();
        res2.reply = format!("BONJOUR {}!", previous);
        writer.write(res2);
        Ok(())
    }

    fn lots_of_greetings(&mut self, reqs: Vec<HelloRequest>) -> GrpcResult<HelloResponse> {
        info!("Say hello");
        let mut msg = String::new();
        msg.push_str("Hello ");
        msg.push_str(&recipients(&reqs));
        let mut res = HelloResponse::new();
        res.reply = msg;
        Ok(res)
    }

    fn bidi_hello(
        &mut self,
        reqs: Vec<HelloRequest>,
        writer: &mut dyn ResponseWriter<HelloResponse>,
    ) -> GrpcResult<()> {
        info!("Say hello");
        let msg = recipients(&reqs);
        let mut res1 = HelloResponse::new();
        res1.reply = format!("HELLO {}!", msg);
        writer.write(res1);
        let mut res2 = HelloResponse::new();
        res2.reply = format!("BONJOUR {}!", msg);
        writer.write(res2);
        Ok(())
    }
}

fn recipients(reqs: &[HelloRequest]) -> String {
    let mut result = String::new();
    for (i, req) in reqs.iter().enumerate() {
        if i > 0 {
            result.push_str(", ");
        }
        result.push_str(&req.greeting);
    }
    result
}
<|endoftext|>


<commit_before>// Copyright 2014-2015 Johannes Köster, Peer Aramillo Irizar.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of alphabets and useful utilities.
//!
//! # Example
//!
//! ```rust
//! use bio::alphabets;
//! let alphabet = alphabets::dna::alphabet();
//! assert!(alphabet.is_word(b"AACCTgga"));
//! assert!(!alphabet.is_word(b"AXYZ"));
//! ```

use std::borrow::Borrow;
use std::mem;

use bit_set::BitSet;
use vec_map::VecMap;

pub mod dna;
pub mod protein;
pub mod rna;

pub type SymbolRanks = VecMap<u8>;

/// Representation of an alphabet.
pub struct Alphabet {
    pub symbols: BitSet,
}

impl Alphabet {
    /// Create new alphabet from given symbols.
    ///
    /// Complexity: O(n), where n is the number of symbols in the alphabet.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// // Create an alphabet (note that a DNA alphabet is already available in bio::alphabets::dna).
    /// let dna_alphabet = alphabets::Alphabet::new(b"ACGTacgt");
    /// // Check whether a given text is a word over the alphabet.
    /// assert!(dna_alphabet.is_word(b"GAttACA"));
    /// ```
    pub fn new<C, T>(symbols: T) -> Self
    where
        C: Borrow<u8>,
        T: IntoIterator<Item = C>,
    {
        let mut s = BitSet::new();
        s.extend(symbols.into_iter().map(|c| *c.borrow() as usize));

        Alphabet { symbols: s }
    }

    /// Insert symbol into alphabet.
    ///
    /// Complexity: O(1)
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let mut dna_alphabet = alphabets::Alphabet::new(b"ACGTacgt");
    /// assert!(!dna_alphabet.is_word(b"N"));
    /// dna_alphabet.insert(78);
    /// assert!(dna_alphabet.is_word(b"N"));
    /// ```
    pub fn insert(&mut self, a: u8) {
        self.symbols.insert(a as usize);
    }

    /// Check if given text is a word over the alphabet.
    ///
    /// Complexity: O(n), where n is the length of the text.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"ACGTacgt");
    /// assert!(dna_alphabet.is_word(b"GAttACA"));
    /// assert!(!dna_alphabet.is_word(b"42"));
    /// ```
    pub fn is_word<C, T>(&self, text: T) -> bool
    where
        C: Borrow<u8>,
        T: IntoIterator<Item = C>,
    {
        text.into_iter()
            .all(|c| self.symbols.contains(*c.borrow() as usize))
    }

    /// Return lexicographically maximal symbol.
    ///
    /// Complexity: O(n), where n is the number of symbols in the alphabet.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"acgtACGT");
    /// assert_eq!(dna_alphabet.max_symbol(), Some(116)); // max symbol is "t"
    /// let empty_alphabet = alphabets::Alphabet::new(b"");
    /// assert_eq!(empty_alphabet.max_symbol(), None);
    /// ```
    pub fn max_symbol(&self) -> Option<u8> {
        self.symbols.iter().max().map(|a| a as u8)
    }

    /// Return size of the alphabet.
    ///
    /// Upper and lower case representations of the same character
    /// are counted as distinct characters.
    ///
    /// Complexity: O(n), where n is the number of symbols in the alphabet.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"acgtACGT");
    /// assert_eq!(dna_alphabet.len(), 8);
    /// ```
    pub fn len(&self) -> usize {
        self.symbols.len()
    }

    /// Is this alphabet empty?
    ///
    /// Complexity: O(n), where n is the number of symbols in the alphabet.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"acgtACGT");
    /// assert!(!dna_alphabet.is_empty());
    /// let empty_alphabet = alphabets::Alphabet::new(b"");
    /// assert!(empty_alphabet.is_empty());
    /// ```
    pub fn is_empty(&self) -> bool {
        self.symbols.is_empty()
    }
}

/// Tools based on transforming the alphabet symbols to their lexicographical ranks.
///
/// Lexicographical rank is computed using `u8` representations,
/// i.e. ASCII codes, of the input characters.
/// For example, assuming that the alphabet consists of the symbols `A`, `C`, `G`, and `T`, this
/// will yield ranks `0`, `1`, `2`, `3` for them, respectively.
///
/// `RankTransform` can be used in to perform bit encoding for texts over a
/// given alphabet via `bio::data_structures::bitenc`.
#[derive(Serialize, Deserialize)]
pub struct RankTransform {
    pub ranks: SymbolRanks,
}

impl RankTransform {
    /// Construct a new `RankTransform`.
    ///
    /// Complexity: O(n), where n is the number of symbols in the alphabet.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"acgtACGT");
    /// let dna_ranks = alphabets::RankTransform::new(&dna_alphabet);
    /// ```
    pub fn new(alphabet: &Alphabet) -> Self {
        let mut ranks = VecMap::new();
        for (r, c) in alphabet.symbols.iter().enumerate() {
            ranks.insert(c, r as u8);
        }

        RankTransform { ranks }
    }

    /// Get the rank of symbol `a`.
    ///
    /// This method panics for characters not contained in the alphabet.
    ///
    /// Complexity: O(1)
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"acgtACGT");
    /// let dna_ranks = alphabets::RankTransform::new(&dna_alphabet);
    /// assert_eq!(dna_ranks.get(65), 0); // "A"
    /// assert_eq!(dna_ranks.get(116), 7); // "t"
    /// ```
    pub fn get(&self, a: u8) -> u8 {
        *self.ranks.get(a as usize).expect("Unexpected character.")
    }

    /// Transform a given `text` into a vector of rank values.
    ///
    /// Complexity: O(n), where n is the length of the text.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"ACGTacgt");
    /// let dna_ranks = alphabets::RankTransform::new(&dna_alphabet);
    /// let text = b"aAcCgGtT";
    /// assert_eq!(dna_ranks.transform(text), vec![4, 0, 5, 1, 6, 2, 7, 3]);
    /// ```
    pub fn transform<C, T>(&self, text: T) -> Vec<u8>
    where
        C: Borrow<u8>,
        T: IntoIterator<Item = C>,
    {
        text.into_iter()
            .map(|c| {
                *self
                    .ranks
                    .get(*c.borrow() as usize)
                    .expect("Unexpected character in text.")
            })
            .collect()
    }

    /// Iterate over q-grams (substrings of length q) of given `text`. The q-grams are encoded
    /// as `usize` by storing the symbol ranks in log2(|A|) bits (with |A| being the alphabet size).
    ///
    /// If q is larger than usize::BITS / log2(|A|), this method fails with an assertion.
    ///
    /// Complexity: O(n), where n is the length of the text.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"ACGTacgt");
    /// let dna_ranks = alphabets::RankTransform::new(&dna_alphabet);
    ///
    /// let q_grams: Vec<usize> = dna_ranks.qgrams(2, b"ACGT").collect();
    /// assert_eq!(q_grams, vec![1, 10, 19]);
    /// ```
    pub fn qgrams<C, T>(&self, q: u32, text: T) -> QGrams<'_, C, T::IntoIter>
    where
        C: Borrow<u8>,
        T: IntoIterator<Item = C>,
    {
        let bits = (self.ranks.len() as f32).log2().ceil() as u32;
        assert!(
            (bits * q) as usize <= mem::size_of::<usize>() * 8,
            "Expecting q to be smaller than usize / log2(|A|)"
        );

        let mut qgrams = QGrams {
            text: text.into_iter(),
            ranks: self,
            bits,
            mask: (1 << (q * bits)) - 1,
            qgram: 0,
        };

        for _ in 0..q - 1 {
            qgrams.next();
        }

        qgrams
    }

    /// Restore alphabet from transform.
    ///
    /// Complexity: O(n), where n is the number of symbols in the alphabet.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"acgtACGT");
    /// let dna_ranks = alphabets::RankTransform::new(&dna_alphabet);
    /// assert_eq!(dna_ranks.alphabet().symbols, dna_alphabet.symbols);
    /// ```
    pub fn alphabet(&self) -> Alphabet {
        let mut symbols = BitSet::with_capacity(self.ranks.len());
        symbols.extend(self.ranks.keys());
        Alphabet { symbols }
    }

    /// Compute the number of bits required to encode the largest rank value.
    ///
    /// For example, the alphabet `b"ACGT"` with 4 symbols has the maximal rank
    /// 3, which can be encoded in 2 bits.
    ///
    /// This value can be used to create a `data_structures::bitenc::BitEnc`
    /// bit encoding tailored to the given alphabet.
    ///
    /// Complexity: O(n), where n is the number of symbols in the alphabet.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"ACGT");
    /// let dna_ranks = alphabets::RankTransform::new(&dna_alphabet);
    /// assert_eq!(dna_ranks.get_width(), 2);
    /// let dna_n_alphabet = alphabets::Alphabet::new(b"ACGTN");
    /// let dna_n_ranks = alphabets::RankTransform::new(&dna_n_alphabet);
    /// assert_eq!(dna_n_ranks.get_width(), 3);
    /// ```
    pub fn get_width(&self) -> usize {
        (self.ranks.len() as f32).log2().ceil() as usize
    }
}

/// Iterator over q-grams.
pub struct QGrams<'a, C, T>
where
    C: Borrow<u8>,
    T: Iterator<Item = C>,
{
    text: T,
    ranks: &'a RankTransform,
    bits: u32,
    mask: usize,
    qgram: usize,
}

impl<'a, C, T> QGrams<'a, C, T>
where
    C: Borrow<u8>,
    T: Iterator<Item = C>,
{
    /// Push a new character into the current qgram.
    fn qgram_push(&mut self, a: u8) {
        self.qgram <<= self.bits;
        self.qgram |= a as usize;
        self.qgram &= self.mask;
    }
}

impl<'a, C, T> Iterator for QGrams<'a, C, T>
where
    C: Borrow<u8>,
    T: Iterator<Item = C>,
{
    type Item = usize;

    fn next(&mut self) -> Option<usize> {
        match self.text.next() {
            Some(a) => {
                let b = self.ranks.get(*a.borrow());
                self.qgram_push(b);
                Some(self.qgram)
            }
            None => None,
        }
    }
}

#[cfg(tests)]
mod tests {
    #[test]
    fn test_serde() {
        use serde::{Deserialize, Serialize};
        fn impls_serde_traits<S: Serialize + Deserialize>() {}

        impls_serde_traits::<RankTransform>();
    }
}
<commit_msg>Add PartialEq and Debug impls for Alphabet. (#367)<commit_after>// Copyright 2014-2015 Johannes Köster, Peer Aramillo Irizar.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of alphabets and useful utilities.
//!
//! # Example
//!
//! ```rust
//! use bio::alphabets;
//! let alphabet = alphabets::dna::alphabet();
//! assert!(alphabet.is_word(b"AACCTgga"));
//! assert!(!alphabet.is_word(b"AXYZ"));
//! ```

use std::borrow::Borrow;
use std::mem;

use bit_set::BitSet;
use vec_map::VecMap;

pub mod dna;
pub mod protein;
pub mod rna;

pub type SymbolRanks = VecMap<u8>;

/// Representation of an alphabet.
#[derive(Debug, PartialEq)]
pub struct Alphabet {
    pub symbols: BitSet,
}

impl Alphabet {
    /// Create new alphabet from given symbols.
    ///
    /// Complexity: O(n), where n is the number of symbols in the alphabet.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// // Create an alphabet (note that a DNA alphabet is already available in bio::alphabets::dna).
    /// let dna_alphabet = alphabets::Alphabet::new(b"ACGTacgt");
    /// // Check whether a given text is a word over the alphabet.
    /// assert!(dna_alphabet.is_word(b"GAttACA"));
    /// ```
    pub fn new<C, T>(symbols: T) -> Self
    where
        C: Borrow<u8>,
        T: IntoIterator<Item = C>,
    {
        let mut s = BitSet::new();
        s.extend(symbols.into_iter().map(|c| *c.borrow() as usize));

        Alphabet { symbols: s }
    }

    /// Insert symbol into alphabet.
    ///
    /// Complexity: O(1)
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let mut dna_alphabet = alphabets::Alphabet::new(b"ACGTacgt");
    /// assert!(!dna_alphabet.is_word(b"N"));
    /// dna_alphabet.insert(78);
    /// assert!(dna_alphabet.is_word(b"N"));
    /// ```
    pub fn insert(&mut self, a: u8) {
        self.symbols.insert(a as usize);
    }

    /// Check if given text is a word over the alphabet.
    ///
    /// Complexity: O(n), where n is the length of the text.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"ACGTacgt");
    /// assert!(dna_alphabet.is_word(b"GAttACA"));
    /// assert!(!dna_alphabet.is_word(b"42"));
    /// ```
    pub fn is_word<C, T>(&self, text: T) -> bool
    where
        C: Borrow<u8>,
        T: IntoIterator<Item = C>,
    {
        text.into_iter()
            .all(|c| self.symbols.contains(*c.borrow() as usize))
    }

    /// Return lexicographically maximal symbol.
    ///
    /// Complexity: O(n), where n is the number of symbols in the alphabet.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"acgtACGT");
    /// assert_eq!(dna_alphabet.max_symbol(), Some(116)); // max symbol is "t"
    /// let empty_alphabet = alphabets::Alphabet::new(b"");
    /// assert_eq!(empty_alphabet.max_symbol(), None);
    /// ```
    pub fn max_symbol(&self) -> Option<u8> {
        self.symbols.iter().max().map(|a| a as u8)
    }

    /// Return size of the alphabet.
    ///
    /// Upper and lower case representations of the same character
    /// are counted as distinct characters.
    ///
    /// Complexity: O(n), where n is the number of symbols in the alphabet.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"acgtACGT");
    /// assert_eq!(dna_alphabet.len(), 8);
    /// ```
    pub fn len(&self) -> usize {
        self.symbols.len()
    }

    /// Is this alphabet empty?
    ///
    /// Complexity: O(n), where n is the number of symbols in the alphabet.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"acgtACGT");
    /// assert!(!dna_alphabet.is_empty());
    /// let empty_alphabet = alphabets::Alphabet::new(b"");
    /// assert!(empty_alphabet.is_empty());
    /// ```
    pub fn is_empty(&self) -> bool {
        self.symbols.is_empty()
    }
}

/// Tools based on transforming the alphabet symbols to their lexicographical ranks.
///
/// Lexicographical rank is computed using `u8` representations,
/// i.e. ASCII codes, of the input characters.
/// For example, assuming that the alphabet consists of the symbols `A`, `C`, `G`, and `T`, this
/// will yield ranks `0`, `1`, `2`, `3` for them, respectively.
///
/// `RankTransform` can be used in to perform bit encoding for texts over a
/// given alphabet via `bio::data_structures::bitenc`.
#[derive(Serialize, Deserialize)]
pub struct RankTransform {
    pub ranks: SymbolRanks,
}

impl RankTransform {
    /// Construct a new `RankTransform`.
    ///
    /// Complexity: O(n), where n is the number of symbols in the alphabet.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"acgtACGT");
    /// let dna_ranks = alphabets::RankTransform::new(&dna_alphabet);
    /// ```
    pub fn new(alphabet: &Alphabet) -> Self {
        let mut ranks = VecMap::new();
        for (r, c) in alphabet.symbols.iter().enumerate() {
            ranks.insert(c, r as u8);
        }

        RankTransform { ranks }
    }

    /// Get the rank of symbol `a`.
    ///
    /// This method panics for characters not contained in the alphabet.
    ///
    /// Complexity: O(1)
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"acgtACGT");
    /// let dna_ranks = alphabets::RankTransform::new(&dna_alphabet);
    /// assert_eq!(dna_ranks.get(65), 0); // "A"
    /// assert_eq!(dna_ranks.get(116), 7); // "t"
    /// ```
    pub fn get(&self, a: u8) -> u8 {
        *self.ranks.get(a as usize).expect("Unexpected character.")
    }

    /// Transform a given `text` into a vector of rank values.
    ///
    /// Complexity: O(n), where n is the length of the text.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"ACGTacgt");
    /// let dna_ranks = alphabets::RankTransform::new(&dna_alphabet);
    /// let text = b"aAcCgGtT";
    /// assert_eq!(dna_ranks.transform(text), vec![4, 0, 5, 1, 6, 2, 7, 3]);
    /// ```
    pub fn transform<C, T>(&self, text: T) -> Vec<u8>
    where
        C: Borrow<u8>,
        T: IntoIterator<Item = C>,
    {
        text.into_iter()
            .map(|c| {
                *self
                    .ranks
                    .get(*c.borrow() as usize)
                    .expect("Unexpected character in text.")
            })
            .collect()
    }

    /// Iterate over q-grams (substrings of length q) of given `text`. The q-grams are encoded
    /// as `usize` by storing the symbol ranks in log2(|A|) bits (with |A| being the alphabet size).
    ///
    /// If q is larger than usize::BITS / log2(|A|), this method fails with an assertion.
    ///
    /// Complexity: O(n), where n is the length of the text.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"ACGTacgt");
    /// let dna_ranks = alphabets::RankTransform::new(&dna_alphabet);
    ///
    /// let q_grams: Vec<usize> = dna_ranks.qgrams(2, b"ACGT").collect();
    /// assert_eq!(q_grams, vec![1, 10, 19]);
    /// ```
    pub fn qgrams<C, T>(&self, q: u32, text: T) -> QGrams<'_, C, T::IntoIter>
    where
        C: Borrow<u8>,
        T: IntoIterator<Item = C>,
    {
        let bits = (self.ranks.len() as f32).log2().ceil() as u32;
        assert!(
            (bits * q) as usize <= mem::size_of::<usize>() * 8,
            "Expecting q to be smaller than usize / log2(|A|)"
        );

        let mut qgrams = QGrams {
            text: text.into_iter(),
            ranks: self,
            bits,
            mask: (1 << (q * bits)) - 1,
            qgram: 0,
        };

        for _ in 0..q - 1 {
            qgrams.next();
        }

        qgrams
    }

    /// Restore alphabet from transform.
    ///
    /// Complexity: O(n), where n is the number of symbols in the alphabet.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"acgtACGT");
    /// let dna_ranks = alphabets::RankTransform::new(&dna_alphabet);
    /// assert_eq!(dna_ranks.alphabet().symbols, dna_alphabet.symbols);
    /// ```
    pub fn alphabet(&self) -> Alphabet {
        let mut symbols = BitSet::with_capacity(self.ranks.len());
        symbols.extend(self.ranks.keys());
        Alphabet { symbols }
    }

    /// Compute the number of bits required to encode the largest rank value.
    ///
    /// For example, the alphabet `b"ACGT"` with 4 symbols has the maximal rank
    /// 3, which can be encoded in 2 bits.
    ///
    /// This value can be used to create a `data_structures::bitenc::BitEnc`
    /// bit encoding tailored to the given alphabet.
    ///
    /// Complexity: O(n), where n is the number of symbols in the alphabet.
    ///
    /// # Example
    ///
    /// ```
    /// use bio::alphabets;
    ///
    /// let dna_alphabet = alphabets::Alphabet::new(b"ACGT");
    /// let dna_ranks = alphabets::RankTransform::new(&dna_alphabet);
    /// assert_eq!(dna_ranks.get_width(), 2);
    /// let dna_n_alphabet = alphabets::Alphabet::new(b"ACGTN");
    /// let dna_n_ranks = alphabets::RankTransform::new(&dna_n_alphabet);
    /// assert_eq!(dna_n_ranks.get_width(), 3);
    /// ```
    pub fn get_width(&self) -> usize {
        (self.ranks.len() as f32).log2().ceil() as usize
    }
}

/// Iterator over q-grams.
pub struct QGrams<'a, C, T>
where
    C: Borrow<u8>,
    T: Iterator<Item = C>,
{
    text: T,
    ranks: &'a RankTransform,
    bits: u32,
    mask: usize,
    qgram: usize,
}

impl<'a, C, T> QGrams<'a, C, T>
where
    C: Borrow<u8>,
    T: Iterator<Item = C>,
{
    /// Push a new character into the current qgram.
    fn qgram_push(&mut self, a: u8) {
        self.qgram <<= self.bits;
        self.qgram |= a as usize;
        self.qgram &= self.mask;
    }
}

impl<'a, C, T> Iterator for QGrams<'a, C, T>
where
    C: Borrow<u8>,
    T: Iterator<Item = C>,
{
    type Item = usize;

    fn next(&mut self) -> Option<usize> {
        match self.text.next() {
            Some(a) => {
                let b = self.ranks.get(*a.borrow());
                self.qgram_push(b);
                Some(self.qgram)
            }
            None => None,
        }
    }
}

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

    #[test]
    fn test_alphabet_eq() {
        assert_eq!(Alphabet::new(b"ATCG"), Alphabet::new(b"ATCG"));
        assert_eq!(Alphabet::new(b"ATCG"), Alphabet::new(b"TAGC"));
        assert_ne!(Alphabet::new(b"ATCG"), Alphabet::new(b"ATC"));
    }
}
<|endoftext|>


<commit_before>
//! library to `gerrit-rust` tool

#![feature(custom_derive)]
#![feature(plugin)]
#![feature(custom_attribute)]
#![feature(proc_macro)]

#[macro_use]
extern crate quick_error;

#[macro_use]
extern crate log;

extern crate curl;
extern crate git2;
extern crate regex;
extern crate url;
extern crate gron;

#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;

pub mod call;
pub mod changes;
pub mod entities;
pub mod error;
pub mod gerrit;

<commit_msg>lib: remove custom_attribute<commit_after>
//! library to `gerrit-rust` tool

#![feature(custom_derive)]
#![feature(plugin)]
#![feature(proc_macro)]

#[macro_use]
extern crate quick_error;

#[macro_use]
extern crate log;

extern crate curl;
extern crate git2;
extern crate regex;
extern crate url;
extern crate gron;

#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;

pub mod call;
pub mod changes;
pub mod entities;
pub mod error;
pub mod gerrit;

<|endoftext|>