<commit_before>extern crate rustc_serialize;

use std::cmp::Ordering;
use std::collections::HashMap;
use std::hash::Hash;
use std::io::prelude::*;
use std::fs::File;

use self::rustc_serialize::json;

use ngrams::ngrams;

pub type StringCountPair = (String, usize);
pub struct Profile {
    pub ngram_ranks: HashMap<String, usize>,
}

impl Profile {
    pub fn build_from_text(text: &str) -> Profile {
        let mut ngram_counts = HashMap::new();
        for n in 1..6 {
            for ngram in ngrams(text, n) {
                *ngram_counts.entry(ngram).or_insert(0usize) += 1;
            }
        }

        let mut ngrams_and_counts = vec_from_hashmap(&ngram_counts);
        ngrams_and_counts.sort_by(cmp_counts_reverse);

        let mut ngram_ranks = HashMap::new();
        for (index, item) in ngrams_and_counts.iter().enumerate() {
            ngram_ranks.insert((*item).clone().0, index);
        }

        Profile { ngram_ranks: ngram_ranks }
    }

    pub fn load_from_file(path: &str) -> Profile {
        let mut f = File::open(path).unwrap();
        let mut encoded_profile = String::new();
        f.read_to_string(&mut encoded_profile);
        let ngram_ranks = json::decode(&encoded_profile).unwrap();
        Profile { ngram_ranks: ngram_ranks }
    }

    pub fn save_to_file(&self, path: &str) {
        let encoded_profile = json::encode(&self.ngram_ranks).unwrap();
        let mut f = File::create(path).unwrap();
        f.write_all(encoded_profile.as_bytes()).unwrap();
    }

    pub fn compare(&self, other: &Profile) -> usize {
        let max_difference = other.ngram_ranks.len();
        let mut difference = 0;
        for (ngram, index) in self.ngram_ranks.iter() {
            difference += match other.ngram_ranks.get(ngram) {
                Some(other_index) => get_difference(*index, *other_index),
                None => max_difference,
            }
        }
        difference
    }
}

// useful utils

fn get_difference(a: usize, b: usize) -> usize {
    if a > b { a - b } else { b - a }
}

fn vec_from_hashmap<K, V> (hashmap: &HashMap<K, V>) -> Vec<(K, V)>
         where K: Eq + Hash + Clone, V: Clone {
    let mut vec: Vec<(K, V)> = Vec::new();
    for (key, value) in hashmap.iter() {
        let item = ((*key).clone(), (*value).clone());
        vec.push(item);
    }
    vec
}

fn cmp_counts_reverse(a: &StringCountPair, b: &StringCountPair) -> Ordering {
    b.1.cmp(&a.1)
}
<commit_msg>StringCountPair doesn't need to be public<commit_after>extern crate rustc_serialize;

use std::cmp::Ordering;
use std::collections::HashMap;
use std::hash::Hash;
use std::io::prelude::*;
use std::fs::File;

use self::rustc_serialize::json;

use ngrams::ngrams;

type StringCountPair = (String, usize);

pub struct Profile {
    pub ngram_ranks: HashMap<String, usize>,
}

impl Profile {
    pub fn build_from_text(text: &str) -> Profile {
        let mut ngram_counts = HashMap::new();
        for n in 1..6 {
            for ngram in ngrams(text, n) {
                *ngram_counts.entry(ngram).or_insert(0usize) += 1;
            }
        }

        let mut ngrams_and_counts = vec_from_hashmap(&ngram_counts);
        ngrams_and_counts.sort_by(cmp_counts_reverse);

        let mut ngram_ranks = HashMap::new();
        for (index, item) in ngrams_and_counts.iter().enumerate() {
            ngram_ranks.insert((*item).clone().0, index);
        }

        Profile { ngram_ranks: ngram_ranks }
    }

    pub fn load_from_file(path: &str) -> Profile {
        let mut f = File::open(path).unwrap();
        let mut encoded_profile = String::new();
        f.read_to_string(&mut encoded_profile);
        let ngram_ranks = json::decode(&encoded_profile).unwrap();
        Profile { ngram_ranks: ngram_ranks }
    }

    pub fn save_to_file(&self, path: &str) {
        let encoded_profile = json::encode(&self.ngram_ranks).unwrap();
        let mut f = File::create(path).unwrap();
        f.write_all(encoded_profile.as_bytes()).unwrap();
    }

    pub fn compare(&self, other: &Profile) -> usize {
        let max_difference = other.ngram_ranks.len();
        let mut difference = 0;
        for (ngram, index) in self.ngram_ranks.iter() {
            difference += match other.ngram_ranks.get(ngram) {
                Some(other_index) => get_difference(*index, *other_index),
                None => max_difference,
            }
        }
        difference
    }
}

// useful utils

fn get_difference(a: usize, b: usize) -> usize {
    if a > b { a - b } else { b - a }
}

fn vec_from_hashmap<K, V> (hashmap: &HashMap<K, V>) -> Vec<(K, V)>
         where K: Eq + Hash + Clone, V: Clone {
    let mut vec: Vec<(K, V)> = Vec::new();
    for (key, value) in hashmap.iter() {
        let item = ((*key).clone(), (*value).clone());
        vec.push(item);
    }
    vec
}

fn cmp_counts_reverse(a: &StringCountPair, b: &StringCountPair) -> Ordering {
    b.1.cmp(&a.1)
}
<|endoftext|>


<commit_before>// Copyright (C) 2016  ParadoxSpiral
//
// This file is part of mpv-rs.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#![allow(dead_code, improper_ctypes, missing_docs, non_camel_case_types)]
use libc;

pub mod prototype {
    #[repr(C)]
    /// This is ok, because you only ever need a `*mut MpvHandle`.
    pub struct MpvHandle;
}

enum_from_primitive! {
    #[repr(C)]
    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
    pub enum MpvError {
        // Success = 0, Handled internally
        EventQueueFull = -1,
        NoMem = -2,
        Uninitialized = -3,
        InvalidParameter = -4,
        OptionNotFound = -5,
        OptionFormat = -6,
        OptionError = -7,
        PropertyNotFound = -8,
        PropertyFormat = -9,
        PropertyUnavailable = -10,
        PropertyError = -11,
        Command = -12,
        LoadingFailed = -13,
        AoInitFailed = -14,
        VoInitFailed = -15,
        NothingToPlay = -16,
        UnknownFormat = -17,
        Unsupported = -18,
        NotImplemented = -19,
        Generic = -20,
    }
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MpvFormat {
    None = 0,
    String = 1,
    OsdString = 2,
    Flag = 3,
    Int64 = 4,
    Double = 5,
    Node = 6,
    NodeArray = 7,
    NodeMap = 8,
    ByteArray = 9,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Eq)]
pub struct MpvNode {
    // FIXME:
    // union {
    // char *string;
    // int flag;
    // int64_t int64;
    // double double_;
    // struct mpv_node_list *list;
    // struct mpv_byte_array *ba;
    // } u;
    pub format: MpvFormat,
}

#[repr(C)]
#[derive(Debug)]
pub struct MpvNodeList {
    pub num: libc::c_int,
    pub values: *mut MpvNode,
    pub keys: *mut *mut libc::c_char,
}

#[repr(C)]
#[derive(Debug)]
pub struct MpvByteArray {
    pub data: *mut libc::c_void,
    pub size: libc::size_t,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MpvEventId {
    None = 0,
    Shutdown = 1,
    LogMessage = 2,
    GetPropertyReply = 3,
    SetPropertyReply = 4,
    CommandReply = 5,
    StartFile = 6,
    EndFile = 7,
    FileLoaded = 8,
    TracksChanged = 9,
    TrackSwitched = 10,
    Idle = 11,
    Pause = 12,
    Unpause = 13,
    Tick = 14,
    ScriptInputDispatch = 15,
    ClientMessage = 16,
    VideoReconfig = 17,
    AudioReconfig = 18,
    MetadataUpdate = 19,
    Seek = 20,
    PlaybackRestart = 21,
    PropertyChange = 22,
    ChapterChange = 23,
    QueueOverflow = 24,
}

#[repr(C)]
#[derive(Debug)]
pub struct MpvEventProperty {
    pub name: *const libc::c_char,
    pub format: MpvFormat,
    pub data: *mut libc::c_void,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MpvLogLevel {
    None = 0,
    Fatal = 10,
    Error = 20,
    Warn = 30,
    Info = 40,
    V = 50,
    Debug = 60,
    Trace = 70,
}

#[repr(C)]
pub struct MpvEventLogMessage {
    pub prefix: *const libc::c_char,
    pub level: *const libc::c_char,
    pub text: *const libc::c_char,
    pub log_level: MpvLogLevel,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MpvEndFileReason {
    Eof = 0,
    Stop = 2,
    Quit = 3,
    Error = 4,
    Redirect = 5,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct MpvEventEndFile {
    pub reason: libc::c_int,
    pub error: libc::c_int,
}

#[repr(C)]
pub struct MpvEventScriptInputDispatch {
    pub arg0: libc::c_int,
    pub type_: *const libc::c_char,
}

#[repr(C)]
pub struct MpvEventClientMessage {
    pub num_args: libc::c_int,
    pub args: *mut *const libc::c_char,
}

#[repr(C)]
pub struct MpvEvent {
    pub event_id: MpvEventId,
    pub error: libc::c_int,
    pub reply_userdata: libc::uint64_t,
    pub data: *mut libc::c_void,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MpvSubApi {
    OpenglCb = 1,
}

pub type mpv_stream_cb_read_fn = extern "C" fn(cookie: *mut libc::c_void,
                                               buf: *mut libc::c_char,
                                               nbytes: libc::uint64_t) -> libc::int64_t;
pub type mpv_stream_cb_seek_fn = extern "C" fn(cookie: *mut libc::c_void, offset: libc::int64_t)
                                                                                -> libc::int64_t;
pub type mpv_stream_cb_size_fn = extern "C" fn(cookie: *mut libc::c_void) -> libc::int64_t;
pub type mpv_stream_cb_close_fn = extern "C" fn(cookie: *mut libc::c_void) -> libc::c_void;

pub type mpv_stream_cb_open_ro_fn = extern "C" fn(user_data: *mut libc::c_void,
                                                  uri: *mut libc::c_char,
                                                  info: *mut mpv_stream_cb_info) -> libc::c_int;
pub type mpv_stream_cb_add_ro = extern "C" fn(ctx: *mut prototype::MpvHandle,
                                              protocol: *const libc::c_char,
                                              user_data: *mut libc::c_void,
                                              open_fn: mpv_stream_cb_open_ro_fn) -> libc::c_int;

#[repr(C)]
pub struct mpv_stream_cb_info {
    pub cookie: *mut libc::c_void,

    pub read_fn: mpv_stream_cb_read_fn,
    pub seek_fn: mpv_stream_cb_seek_fn,
    pub size_fn: mpv_stream_cb_size_fn,
    pub close_fn: mpv_stream_cb_close_fn,
}

#[cfg_attr(feature="static", link(name = "mpv", kind = "static"))]
#[cfg_attr(not(feature="static"), link(name = "mpv"))]
extern "C" {
    pub fn mpv_client_api_version() -> u32;
    pub fn mpv_error_string(error: libc::c_int) -> *const libc::c_char;
    pub fn mpv_free(data: *mut libc::c_void);
    pub fn mpv_client_name(ctx: *const prototype::MpvHandle) -> *const libc::c_char;
    pub fn mpv_create() -> *mut prototype::MpvHandle;
    pub fn mpv_initialize(ctx: *mut prototype::MpvHandle) -> libc::c_int;
    pub fn mpv_detach_destroy(ctx: *mut prototype::MpvHandle);
    pub fn mpv_terminate_destroy(ctx: *mut prototype::MpvHandle);
    pub fn mpv_create_client(ctx: *mut prototype::MpvHandle,
                             name: *const libc::c_char)
                             -> *mut prototype::MpvHandle;
    pub fn mpv_load_config_file(ctx: *mut prototype::MpvHandle,
                                filename: *const libc::c_char)
                                -> libc::c_int;
    pub fn mpv_suspend(ctx: *mut prototype::MpvHandle);
    pub fn mpv_resume(ctx: *mut prototype::MpvHandle);
    pub fn mpv_free_node_contents(node: *mut MpvNode);
    pub fn mpv_set_option(ctx: *mut prototype::MpvHandle,
                          name: *const libc::c_char,
                          format: libc::c_int,
                          data: *mut libc::c_void)
                          -> libc::c_int;
    pub fn mpv_set_option_string(ctx: *mut prototype::MpvHandle,
                                 name: *const libc::c_char,
                                 data: *const libc::c_char)
                                 -> libc::c_int;
    pub fn mpv_command(ctx: *mut prototype::MpvHandle,
                       args: *mut *const libc::c_char)
                       -> libc::c_int;
    pub fn mpv_command_node(ctx: *mut prototype::MpvHandle,
                            args: *mut MpvNode,
                            result: *mut MpvNode)
                            -> libc::c_int;
    pub fn mpv_command_string(ctx: *mut prototype::MpvHandle,
                              args: *const libc::c_char)
                              -> libc::c_int;
    pub fn mpv_get_time_us(ctx: *mut prototype::MpvHandle) -> libc::int64_t;
    pub fn mpv_command_async(ctx: *mut prototype::MpvHandle,
                             reply_userdata: libc::uint64_t,
                             args: *const *const libc::c_char)
                             -> libc::c_int;
    pub fn mpv_set_property(ctx: *mut prototype::MpvHandle,
                            name: *const libc::c_char,
                            format: libc::c_int,
                            data: *mut libc::c_void)
                            -> libc::c_int;
    pub fn mpv_set_property_string(ctx: *mut prototype::MpvHandle,
                                   name: *const libc::c_char,
                                   data: *const libc::c_char)
                                   -> libc::c_int;
    pub fn mpv_set_property_async(ctx: *mut prototype::MpvHandle,
                                  reply_userdata: libc::uint64_t,
                                  name: *const libc::c_char,
                                  format: libc::c_int,
                                  data: *mut libc::c_void)
                                  -> libc::c_int;
    pub fn mpv_get_property(ctx: *mut prototype::MpvHandle,
                            name: *const libc::c_char,
                            format: libc::c_int,
                            data: *mut libc::c_void)
                            -> libc::c_int;
    pub fn mpv_get_property_string(ctx: *mut prototype::MpvHandle,
                                   name: *const libc::c_char)
                                   -> *mut libc::c_char;
    pub fn mpv_get_property_osd_string(ctx: *mut prototype::MpvHandle,
                                       name: *const libc::c_char)
                                       -> *mut libc::c_char;
    pub fn mpv_get_property_async(ctx: *mut prototype::MpvHandle,
                                  reply_userdata: libc::uint64_t,
                                  name: *const libc::c_char,
                                  format: libc::c_int)
                                  -> libc::c_int;
    pub fn mpv_observe_property(mpv: *mut prototype::MpvHandle,
                                reply_userdata: libc::uint64_t,
                                name: *const libc::c_char,
                                format: libc::c_int)
                                -> libc::c_int;
    pub fn mpv_unobserve_property(mpv: *mut prototype::MpvHandle,
                                  registered_reply_userdata: libc::uint64_t)
                                  -> libc::c_int;
    pub fn mpv_event_name(event: MpvEventId) -> *const libc::c_char;
    pub fn mpv_request_event(ctx: *mut prototype::MpvHandle,
                             event: MpvEventId,
                             enable: libc::c_int)
                             -> libc::c_int;
    pub fn mpv_request_log_messages(ctx: *mut prototype::MpvHandle,
                                    min_level: *const libc::c_char)
                                    -> libc::c_int;
    pub fn mpv_wait_event(ctx: *mut prototype::MpvHandle,
                          timeout: libc::c_double)
                          -> *mut MpvEvent;
    pub fn mpv_wakeup(ctx: *mut prototype::MpvHandle);
    pub fn mpv_set_wakeup_callback(ctx: *mut prototype::MpvHandle,
                                   cb: unsafe extern "C" fn(*mut libc::c_void),
                                   d: *mut libc::c_void);
    pub fn mpv_get_wakeup_pipe(ctx: *mut prototype::MpvHandle) -> libc::c_int;
    pub fn mpv_wait_async_requests(ctx: *mut prototype::MpvHandle);
    pub fn mpv_get_sub_api(ctx: *mut prototype::MpvHandle, sub_api: MpvSubApi);
}
<commit_msg>Fix last commit<commit_after>// Copyright (C) 2016  ParadoxSpiral
//
// This file is part of mpv-rs.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#![allow(dead_code, improper_ctypes, missing_docs, non_camel_case_types)]
use libc;

pub mod prototype {
    #[repr(C)]
    /// This is ok, because you only ever need a `*mut MpvHandle`.
    pub struct MpvHandle;
}

enum_from_primitive! {
    #[repr(C)]
    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
    pub enum MpvError {
        // Success = 0, Handled internally
        EventQueueFull = -1,
        NoMem = -2,
        Uninitialized = -3,
        InvalidParameter = -4,
        OptionNotFound = -5,
        OptionFormat = -6,
        OptionError = -7,
        PropertyNotFound = -8,
        PropertyFormat = -9,
        PropertyUnavailable = -10,
        PropertyError = -11,
        Command = -12,
        LoadingFailed = -13,
        AoInitFailed = -14,
        VoInitFailed = -15,
        NothingToPlay = -16,
        UnknownFormat = -17,
        Unsupported = -18,
        NotImplemented = -19,
        Generic = -20,
    }
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MpvFormat {
    None = 0,
    String = 1,
    OsdString = 2,
    Flag = 3,
    Int64 = 4,
    Double = 5,
    Node = 6,
    NodeArray = 7,
    NodeMap = 8,
    ByteArray = 9,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Eq)]
pub struct MpvNode {
    // FIXME:
    // union {
    // char *string;
    // int flag;
    // int64_t int64;
    // double double_;
    // struct mpv_node_list *list;
    // struct mpv_byte_array *ba;
    // } u;
    pub format: MpvFormat,
}

#[repr(C)]
#[derive(Debug)]
pub struct MpvNodeList {
    pub num: libc::c_int,
    pub values: *mut MpvNode,
    pub keys: *mut *mut libc::c_char,
}

#[repr(C)]
#[derive(Debug)]
pub struct MpvByteArray {
    pub data: *mut libc::c_void,
    pub size: libc::size_t,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MpvEventId {
    None = 0,
    Shutdown = 1,
    LogMessage = 2,
    GetPropertyReply = 3,
    SetPropertyReply = 4,
    CommandReply = 5,
    StartFile = 6,
    EndFile = 7,
    FileLoaded = 8,
    TracksChanged = 9,
    TrackSwitched = 10,
    Idle = 11,
    Pause = 12,
    Unpause = 13,
    Tick = 14,
    ScriptInputDispatch = 15,
    ClientMessage = 16,
    VideoReconfig = 17,
    AudioReconfig = 18,
    MetadataUpdate = 19,
    Seek = 20,
    PlaybackRestart = 21,
    PropertyChange = 22,
    ChapterChange = 23,
    QueueOverflow = 24,
}

#[repr(C)]
#[derive(Debug)]
pub struct MpvEventProperty {
    pub name: *const libc::c_char,
    pub format: MpvFormat,
    pub data: *mut libc::c_void,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MpvLogLevel {
    None = 0,
    Fatal = 10,
    Error = 20,
    Warn = 30,
    Info = 40,
    V = 50,
    Debug = 60,
    Trace = 70,
}

#[repr(C)]
pub struct MpvEventLogMessage {
    pub prefix: *const libc::c_char,
    pub level: *const libc::c_char,
    pub text: *const libc::c_char,
    pub log_level: MpvLogLevel,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MpvEndFileReason {
    Eof = 0,
    Stop = 2,
    Quit = 3,
    Error = 4,
    Redirect = 5,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct MpvEventEndFile {
    pub reason: libc::c_int,
    pub error: libc::c_int,
}

#[repr(C)]
pub struct MpvEventScriptInputDispatch {
    pub arg0: libc::c_int,
    pub type_: *const libc::c_char,
}

#[repr(C)]
pub struct MpvEventClientMessage {
    pub num_args: libc::c_int,
    pub args: *mut *const libc::c_char,
}

#[repr(C)]
pub struct MpvEvent {
    pub event_id: MpvEventId,
    pub error: libc::c_int,
    pub reply_userdata: libc::uint64_t,
    pub data: *mut libc::c_void,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MpvSubApi {
    OpenglCb = 1,
}

pub type mpv_stream_cb_read_fn = extern "C" fn(cookie: *mut libc::c_void,
                                               buf: *mut libc::c_char,
                                               nbytes: libc::uint64_t) -> libc::int64_t;
pub type mpv_stream_cb_seek_fn = extern "C" fn(cookie: *mut libc::c_void, offset: libc::int64_t)
                                                                                -> libc::int64_t;
pub type mpv_stream_cb_size_fn = extern "C" fn(cookie: *mut libc::c_void) -> libc::int64_t;
pub type mpv_stream_cb_close_fn = extern "C" fn(cookie: *mut libc::c_void) -> libc::c_void;

pub type mpv_stream_cb_open_ro_fn = extern "C" fn(user_data: *mut libc::c_void,
                                                  uri: *mut libc::c_char,
                                                  info: *mut MpvStreamCbInfo) -> libc::c_int;

#[repr(C)]
pub struct MpvStreamCbInfo {
    pub cookie: *mut libc::c_void,

    pub read_fn: mpv_stream_cb_read_fn,
    pub seek_fn: mpv_stream_cb_seek_fn,
    pub size_fn: mpv_stream_cb_size_fn,
    pub close_fn: mpv_stream_cb_close_fn,
}

#[cfg_attr(feature="static", link(name = "mpv", kind = "static"))]
#[cfg_attr(not(feature="static"), link(name = "mpv"))]
extern "C" {
    pub fn mpv_client_api_version() -> u32;
    pub fn mpv_error_string(error: libc::c_int) -> *const libc::c_char;
    pub fn mpv_free(data: *mut libc::c_void);
    pub fn mpv_client_name(ctx: *const prototype::MpvHandle) -> *const libc::c_char;
    pub fn mpv_create() -> *mut prototype::MpvHandle;
    pub fn mpv_initialize(ctx: *mut prototype::MpvHandle) -> libc::c_int;
    pub fn mpv_detach_destroy(ctx: *mut prototype::MpvHandle);
    pub fn mpv_terminate_destroy(ctx: *mut prototype::MpvHandle);
    pub fn mpv_create_client(ctx: *mut prototype::MpvHandle,
                             name: *const libc::c_char)
                             -> *mut prototype::MpvHandle;
    pub fn mpv_load_config_file(ctx: *mut prototype::MpvHandle,
                                filename: *const libc::c_char)
                                -> libc::c_int;
    pub fn mpv_suspend(ctx: *mut prototype::MpvHandle);
    pub fn mpv_resume(ctx: *mut prototype::MpvHandle);
    pub fn mpv_free_node_contents(node: *mut MpvNode);
    pub fn mpv_set_option(ctx: *mut prototype::MpvHandle,
                          name: *const libc::c_char,
                          format: libc::c_int,
                          data: *mut libc::c_void)
                          -> libc::c_int;
    pub fn mpv_set_option_string(ctx: *mut prototype::MpvHandle,
                                 name: *const libc::c_char,
                                 data: *const libc::c_char)
                                 -> libc::c_int;
    pub fn mpv_command(ctx: *mut prototype::MpvHandle,
                       args: *mut *const libc::c_char)
                       -> libc::c_int;
    pub fn mpv_command_node(ctx: *mut prototype::MpvHandle,
                            args: *mut MpvNode,
                            result: *mut MpvNode)
                            -> libc::c_int;
    pub fn mpv_command_string(ctx: *mut prototype::MpvHandle,
                              args: *const libc::c_char)
                              -> libc::c_int;
    pub fn mpv_get_time_us(ctx: *mut prototype::MpvHandle) -> libc::int64_t;
    pub fn mpv_command_async(ctx: *mut prototype::MpvHandle,
                             reply_userdata: libc::uint64_t,
                             args: *const *const libc::c_char)
                             -> libc::c_int;
    pub fn mpv_set_property(ctx: *mut prototype::MpvHandle,
                            name: *const libc::c_char,
                            format: libc::c_int,
                            data: *mut libc::c_void)
                            -> libc::c_int;
    pub fn mpv_set_property_string(ctx: *mut prototype::MpvHandle,
                                   name: *const libc::c_char,
                                   data: *const libc::c_char)
                                   -> libc::c_int;
    pub fn mpv_set_property_async(ctx: *mut prototype::MpvHandle,
                                  reply_userdata: libc::uint64_t,
                                  name: *const libc::c_char,
                                  format: libc::c_int,
                                  data: *mut libc::c_void)
                                  -> libc::c_int;
    pub fn mpv_get_property(ctx: *mut prototype::MpvHandle,
                            name: *const libc::c_char,
                            format: libc::c_int,
                            data: *mut libc::c_void)
                            -> libc::c_int;
    pub fn mpv_get_property_string(ctx: *mut prototype::MpvHandle,
                                   name: *const libc::c_char)
                                   -> *mut libc::c_char;
    pub fn mpv_get_property_osd_string(ctx: *mut prototype::MpvHandle,
                                       name: *const libc::c_char)
                                       -> *mut libc::c_char;
    pub fn mpv_get_property_async(ctx: *mut prototype::MpvHandle,
                                  reply_userdata: libc::uint64_t,
                                  name: *const libc::c_char,
                                  format: libc::c_int)
                                  -> libc::c_int;
    pub fn mpv_observe_property(mpv: *mut prototype::MpvHandle,
                                reply_userdata: libc::uint64_t,
                                name: *const libc::c_char,
                                format: libc::c_int)
                                -> libc::c_int;
    pub fn mpv_unobserve_property(mpv: *mut prototype::MpvHandle,
                                  registered_reply_userdata: libc::uint64_t)
                                  -> libc::c_int;
    pub fn mpv_event_name(event: MpvEventId) -> *const libc::c_char;
    pub fn mpv_request_event(ctx: *mut prototype::MpvHandle,
                             event: MpvEventId,
                             enable: libc::c_int)
                             -> libc::c_int;
    pub fn mpv_request_log_messages(ctx: *mut prototype::MpvHandle,
                                    min_level: *const libc::c_char)
                                    -> libc::c_int;
    pub fn mpv_wait_event(ctx: *mut prototype::MpvHandle,
                          timeout: libc::c_double)
                          -> *mut MpvEvent;
    pub fn mpv_wakeup(ctx: *mut prototype::MpvHandle);
    pub fn mpv_set_wakeup_callback(ctx: *mut prototype::MpvHandle,
                                   cb: unsafe extern "C" fn(*mut libc::c_void),
                                   d: *mut libc::c_void);
    pub fn mpv_get_wakeup_pipe(ctx: *mut prototype::MpvHandle) -> libc::c_int;
    pub fn mpv_wait_async_requests(ctx: *mut prototype::MpvHandle);
    pub fn mpv_get_sub_api(ctx: *mut prototype::MpvHandle, sub_api: MpvSubApi);
    pub fn mpv_stream_cb_add_ro(ctx: *mut prototype::MpvHandle,
                                protocol: *const libc::c_char,
                                user_data: *mut libc::c_void,
                                open_fn: mpv_stream_cb_open_ro_fn)
                                -> libc::c_int;
}
<|endoftext|>


<commit_before>pub trait EventHandler<T: Event, D> {
    fn handle_event(&mut self, event: T, shared_data: &mut D);
    fn handle(&self) -> T::Handle;
}

pub trait EventDemultiplexer {
    type Event: Event;
    fn select(&mut self) -> Option<Self::Event>;
}

pub trait Reactor<D> {
    type Event: Event;
    fn handle_events(&mut self);
    fn register_handler(&mut self, handler: Box<EventHandler<Self::Event, D>>);
    fn remove_handler_by_handle(&mut self,
                                 handler: &<<Self as Reactor<D>>::Event as Event>::Handle);
}

pub trait Event {
    type Handle;
    fn handle(&self) -> Self::Handle;
}
<commit_msg>reactor: add SharedDate struct<commit_after>use dispatcher::response::ResponseSender;
use context::ContextMap;

pub struct SharedData<'a> {
    pub responder: &'a mut ResponseSender,
    pub map: &'a mut ContextMap,
}

impl<'a> SharedData<'a> {
    pub fn new(map: &'a mut ContextMap, responder: &'a mut ResponseSender) -> SharedData<'a> {
        SharedData { map: map, responder: responder }
    }
}

pub trait EventHandler<T: Event, D> {
    fn handle_event(&mut self, event: T, shared_data: &mut D);
    fn handle(&self) -> T::Handle;
}

pub trait EventDemultiplexer {
    type Event: Event;
    fn select(&mut self) -> Option<Self::Event>;
}

pub trait Reactor<D> {
    type Event: Event;
    fn handle_events(&mut self);
    fn register_handler(&mut self, handler: Box<EventHandler<Self::Event, D>>);
    fn remove_handler_by_handle(&mut self,
                                 handler: &<<Self as Reactor<D>>::Event as Event>::Handle);
}

pub trait Event {
    type Handle;
    fn handle(&self) -> Self::Handle;
}
<|endoftext|>


<commit_before>fn main() {
   // sum up even elements of Fibonacci sequence
   // which not exceed 4.000.000
   let (a, b) = (1, 2);

   println!("The sum of all even Fibonacci elements with value below 4.000.000 equals to: {}", 0);
}
<commit_msg>Added Fib struct and sequence generator<commit_after>struct Fibonacci {
    current: u32,
    next: u32,
}

fn fibonacci() -> Fibonacci {
    Fibonacci {
        current: 1,
        next: 1,
    }
}

//TODO implement the iterator for Fibonacci

fn main() {
   // sum up even elements of Fibonacci sequence
   // which not exceed 4.000.000
   let (a, b) = (1, 1);

   println!("The sum of all even Fibonacci elements with value below 4.000.000 equals to: {}", 0);
}
<|endoftext|>


<commit_before>#![warn(clippy::all)]
#![cfg_attr(feature = "nightly",
            feature(never_type),
            feature(const_saturating_int_methods))]
#![cfg_attr(all(test, feature = "nightly"), feature(test))]
#[cfg(all(test, feature = "nightly"))]
extern crate test;

// Define a never type useful for some traits (ie. SetupRequest)
#[cfg(feature = "nightly")]
pub type Never = !;
#[cfg(not(feature = "nightly"))]
pub type Never = core::convert::Infallible;

pub mod api_call;
pub mod application;
pub mod credentials;
pub mod encoding;
pub mod errors;
pub mod extensions;
pub mod http;
pub mod service;
pub mod transaction;
pub mod usage;
pub mod user;
pub mod version;

#[cfg(feature = "xml-response")]
pub mod response;
pub mod timestamp;

use std::borrow::Cow;

/// This is the trait to be implemented by structures that can set parameters to API calls.
///
/// Note that the 'this lifetime requires a lifetime long enough to keep keys and values.
/// The keys can potentially be modified to adapt them to the specific call circumstances,
/// so in order to take advantage of single allocations when modifications are not needed,
/// a copy-on-write type is used. Values are always kept as is, so just references are ok.
pub(crate) trait ToParams<'k, 'v, 'this, E>
    where 'this: 'k + 'v,
          E: Extend<(Cow<'k, str>, &'v str)>
{
    fn to_params(&'this self, extendable: &mut E) {
        self.to_params_with_prefix(extendable, None);
    }

    fn to_params_with_prefix(&'this self, extendable: &mut E, prefix: Option<&'k str>) {
        self.to_params_with_mangling(extendable, &mut |c| match prefix {
                Some(p) => c + p,
                _ => c,
            });
    }

    fn to_params_with_mangling<F: FnMut(Cow<'k, str>) -> Cow<'k, str>>(&'this self,
                                                                       extendable: &mut E,
                                                                       key_mangling: &mut F);
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<commit_msg>src/lib: feature(never_type) no longer required in nightly<commit_after>#![warn(clippy::all)]
#![cfg_attr(feature = "nightly",
            feature(const_saturating_int_methods))]
#![cfg_attr(all(test, feature = "nightly"), feature(test))]
#[cfg(all(test, feature = "nightly"))]
extern crate test;

// Define a never type useful for some traits (ie. SetupRequest)
#[cfg(feature = "nightly")]
pub type Never = !;
#[cfg(not(feature = "nightly"))]
pub type Never = core::convert::Infallible;

pub mod api_call;
pub mod application;
pub mod credentials;
pub mod encoding;
pub mod errors;
pub mod extensions;
pub mod http;
pub mod service;
pub mod transaction;
pub mod usage;
pub mod user;
pub mod version;

#[cfg(feature = "xml-response")]
pub mod response;
pub mod timestamp;

use std::borrow::Cow;

/// This is the trait to be implemented by structures that can set parameters to API calls.
///
/// Note that the 'this lifetime requires a lifetime long enough to keep keys and values.
/// The keys can potentially be modified to adapt them to the specific call circumstances,
/// so in order to take advantage of single allocations when modifications are not needed,
/// a copy-on-write type is used. Values are always kept as is, so just references are ok.
pub(crate) trait ToParams<'k, 'v, 'this, E>
    where 'this: 'k + 'v,
          E: Extend<(Cow<'k, str>, &'v str)>
{
    fn to_params(&'this self, extendable: &mut E) {
        self.to_params_with_prefix(extendable, None);
    }

    fn to_params_with_prefix(&'this self, extendable: &mut E, prefix: Option<&'k str>) {
        self.to_params_with_mangling(extendable, &mut |c| match prefix {
                Some(p) => c + p,
                _ => c,
            });
    }

    fn to_params_with_mangling<F: FnMut(Cow<'k, str>) -> Cow<'k, str>>(&'this self,
                                                                       extendable: &mut E,
                                                                       key_mangling: &mut F);
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<|endoftext|>


<commit_before>#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)]
extern crate libc;
/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Copy)]
pub struct Struct_TLimits {
    pub nonInductiveForLoops: u8,
    pub whileLoops: u8,
    pub doWhileLoops: u8,
    pub generalUniformIndexing: u8,
    pub generalAttributeMatrixVectorIndexing: u8,
    pub generalVaryingIndexing: u8,
    pub generalSamplerIndexing: u8,
    pub generalVariableIndexing: u8,
    pub generalConstantMatrixVectorIndexing: u8,
}
impl ::std::clone::Clone for Struct_TLimits {
    fn clone(&self) -> Self { *self }
}
impl ::std::default::Default for Struct_TLimits {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
pub type TLimits = Struct_TLimits;
#[repr(C)]
#[derive(Copy)]
pub struct Struct_TBuiltInResource {
    pub maxLights: ::libc::c_int,
    pub maxClipPlanes: ::libc::c_int,
    pub maxTextureUnits: ::libc::c_int,
    pub maxTextureCoords: ::libc::c_int,
    pub maxVertexAttribs: ::libc::c_int,
    pub maxVertexUniformComponents: ::libc::c_int,
    pub maxVaryingFloats: ::libc::c_int,
    pub maxVertexTextureImageUnits: ::libc::c_int,
    pub maxCombinedTextureImageUnits: ::libc::c_int,
    pub maxTextureImageUnits: ::libc::c_int,
    pub maxFragmentUniformComponents: ::libc::c_int,
    pub maxDrawBuffers: ::libc::c_int,
    pub maxVertexUniformVectors: ::libc::c_int,
    pub maxVaryingVectors: ::libc::c_int,
    pub maxFragmentUniformVectors: ::libc::c_int,
    pub maxVertexOutputVectors: ::libc::c_int,
    pub maxFragmentInputVectors: ::libc::c_int,
    pub minProgramTexelOffset: ::libc::c_int,
    pub maxProgramTexelOffset: ::libc::c_int,
    pub maxClipDistances: ::libc::c_int,
    pub maxComputeWorkGroupCountX: ::libc::c_int,
    pub maxComputeWorkGroupCountY: ::libc::c_int,
    pub maxComputeWorkGroupCountZ: ::libc::c_int,
    pub maxComputeWorkGroupSizeX: ::libc::c_int,
    pub maxComputeWorkGroupSizeY: ::libc::c_int,
    pub maxComputeWorkGroupSizeZ: ::libc::c_int,
    pub maxComputeUniformComponents: ::libc::c_int,
    pub maxComputeTextureImageUnits: ::libc::c_int,
    pub maxComputeImageUniforms: ::libc::c_int,
    pub maxComputeAtomicCounters: ::libc::c_int,
    pub maxComputeAtomicCounterBuffers: ::libc::c_int,
    pub maxVaryingComponents: ::libc::c_int,
    pub maxVertexOutputComponents: ::libc::c_int,
    pub maxGeometryInputComponents: ::libc::c_int,
    pub maxGeometryOutputComponents: ::libc::c_int,
    pub maxFragmentInputComponents: ::libc::c_int,
    pub maxImageUnits: ::libc::c_int,
    pub maxCombinedImageUnitsAndFragmentOutputs: ::libc::c_int,
    pub maxCombinedShaderOutputResources: ::libc::c_int,
    pub maxImageSamples: ::libc::c_int,
    pub maxVertexImageUniforms: ::libc::c_int,
    pub maxTessControlImageUniforms: ::libc::c_int,
    pub maxTessEvaluationImageUniforms: ::libc::c_int,
    pub maxGeometryImageUniforms: ::libc::c_int,
    pub maxFragmentImageUniforms: ::libc::c_int,
    pub maxCombinedImageUniforms: ::libc::c_int,
    pub maxGeometryTextureImageUnits: ::libc::c_int,
    pub maxGeometryOutputVertices: ::libc::c_int,
    pub maxGeometryTotalOutputComponents: ::libc::c_int,
    pub maxGeometryUniformComponents: ::libc::c_int,
    pub maxGeometryVaryingComponents: ::libc::c_int,
    pub maxTessControlInputComponents: ::libc::c_int,
    pub maxTessControlOutputComponents: ::libc::c_int,
    pub maxTessControlTextureImageUnits: ::libc::c_int,
    pub maxTessControlUniformComponents: ::libc::c_int,
    pub maxTessControlTotalOutputComponents: ::libc::c_int,
    pub maxTessEvaluationInputComponents: ::libc::c_int,
    pub maxTessEvaluationOutputComponents: ::libc::c_int,
    pub maxTessEvaluationTextureImageUnits: ::libc::c_int,
    pub maxTessEvaluationUniformComponents: ::libc::c_int,
    pub maxTessPatchComponents: ::libc::c_int,
    pub maxPatchVertices: ::libc::c_int,
    pub maxTessGenLevel: ::libc::c_int,
    pub maxViewports: ::libc::c_int,
    pub maxVertexAtomicCounters: ::libc::c_int,
    pub maxTessControlAtomicCounters: ::libc::c_int,
    pub maxTessEvaluationAtomicCounters: ::libc::c_int,
    pub maxGeometryAtomicCounters: ::libc::c_int,
    pub maxFragmentAtomicCounters: ::libc::c_int,
    pub maxCombinedAtomicCounters: ::libc::c_int,
    pub maxAtomicCounterBindings: ::libc::c_int,
    pub maxVertexAtomicCounterBuffers: ::libc::c_int,
    pub maxTessControlAtomicCounterBuffers: ::libc::c_int,
    pub maxTessEvaluationAtomicCounterBuffers: ::libc::c_int,
    pub maxGeometryAtomicCounterBuffers: ::libc::c_int,
    pub maxFragmentAtomicCounterBuffers: ::libc::c_int,
    pub maxCombinedAtomicCounterBuffers: ::libc::c_int,
    pub maxAtomicCounterBufferSize: ::libc::c_int,
    pub maxTransformFeedbackBuffers: ::libc::c_int,
    pub maxTransformFeedbackInterleavedComponents: ::libc::c_int,
    pub maxCullDistances: ::libc::c_int,
    pub maxCombinedClipAndCullDistances: ::libc::c_int,
    pub maxSamples: ::libc::c_int,
    pub limits: TLimits,
}
impl ::std::clone::Clone for Struct_TBuiltInResource {
    fn clone(&self) -> Self { *self }
}
impl ::std::default::Default for Struct_TBuiltInResource {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
pub type TBuiltInResource = Struct_TBuiltInResource;
pub type Enum_Unnamed1 = ::libc::c_uint;
pub const EShLangVertex: ::libc::c_uint = 0;
pub const EShLangTessControl: ::libc::c_uint = 1;
pub const EShLangTessEvaluation: ::libc::c_uint = 2;
pub const EShLangGeometry: ::libc::c_uint = 3;
pub const EShLangFragment: ::libc::c_uint = 4;
pub const EShLangCompute: ::libc::c_uint = 5;
pub const EShLangCount: ::libc::c_uint = 6;
pub type EShLanguage = Enum_Unnamed1;
pub type Enum_Unnamed2 = ::libc::c_uint;
pub const EShLangVertexMask: ::libc::c_uint = 1;
pub const EShLangTessControlMask: ::libc::c_uint = 2;
pub const EShLangTessEvaluationMask: ::libc::c_uint = 4;
pub const EShLangGeometryMask: ::libc::c_uint = 8;
pub const EShLangFragmentMask: ::libc::c_uint = 16;
pub const EShLangComputeMask: ::libc::c_uint = 32;
pub type EShLanguageMask = Enum_Unnamed2;
pub type Enum_EShExecutable = ::libc::c_uint;
pub const EShExVertexFragment: ::libc::c_uint = 0;
pub const EShExFragment: ::libc::c_uint = 1;
pub type EShExecutable = Enum_EShExecutable;
pub type Enum_EShOptimizationLevel = ::libc::c_uint;
pub const EShOptNoGeneration: ::libc::c_uint = 0;
pub const EShOptNone: ::libc::c_uint = 1;
pub const EShOptSimple: ::libc::c_uint = 2;
pub const EShOptFull: ::libc::c_uint = 3;
pub type EShOptimizationLevel = Enum_EShOptimizationLevel;
pub type Enum_EShMessages = ::libc::c_uint;
pub const EShMsgDefault: ::libc::c_uint = 0;
pub const EShMsgRelaxedErrors: ::libc::c_uint = 1;
pub const EShMsgSuppressWarnings: ::libc::c_uint = 2;
pub const EShMsgAST: ::libc::c_uint = 4;
pub type EShMessages = Enum_EShMessages;
#[repr(C)]
#[derive(Copy)]
pub struct Struct_ShBinding {
    pub name: *const ::libc::c_char,
    pub binding: ::libc::c_int,
}
impl ::std::clone::Clone for Struct_ShBinding {
    fn clone(&self) -> Self { *self }
}
impl ::std::default::Default for Struct_ShBinding {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
pub type ShBinding = Struct_ShBinding;
#[repr(C)]
#[derive(Copy)]
pub struct Struct_ShBindingTable {
    pub numBindings: ::libc::c_int,
    pub bindings: *mut ShBinding,
}
impl ::std::clone::Clone for Struct_ShBindingTable {
    fn clone(&self) -> Self { *self }
}
impl ::std::default::Default for Struct_ShBindingTable {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
pub type ShBindingTable = Struct_ShBindingTable;
pub type ShHandle = *mut ::libc::c_void;
extern "C" {
    pub fn ShInitialize() -> ::libc::c_int;
    pub fn ShFinalize() -> ::libc::c_int;
    pub fn StageName(arg1: EShLanguage) -> *const ::libc::c_char;
    pub fn ShConstructCompiler(arg1: EShLanguage, debugOptions: ::libc::c_int)
     -> ShHandle;
    pub fn ShConstructLinker(arg1: EShExecutable, debugOptions: ::libc::c_int)
     -> ShHandle;
    pub fn ShConstructUniformMap() -> ShHandle;
    pub fn ShDestruct(arg1: ShHandle) -> ();
    pub fn ShCompile(arg1: ShHandle,
                     shaderStrings: *const *const ::libc::c_char,
                     numStrings: ::libc::c_int, lengths: *const ::libc::c_int,
                     arg2: EShOptimizationLevel,
                     resources: *const TBuiltInResource,
                     debugOptions: ::libc::c_int,
                     defaultVersion: ::libc::c_int, forwardCompatible: u8,
                     messages: EShMessages) -> ::libc::c_int;
    pub fn ShLink(arg1: ShHandle, h: *const ShHandle,
                  numHandles: ::libc::c_int, uniformMap: ShHandle,
                  uniformsAccessed: *mut *mut ::libc::c_short,
                  numUniformsAccessed: *mut ::libc::c_int) -> ::libc::c_int;
    pub fn ShLinkExt(arg1: ShHandle, h: *const ShHandle,
                     numHandles: ::libc::c_int) -> ::libc::c_int;
    pub fn ShSetEncryptionMethod(arg1: ShHandle) -> ();
    pub fn ShGetInfoLog(arg1: ShHandle) -> *const ::libc::c_char;
    pub fn ShGetExecutable(arg1: ShHandle) -> *const ::libc::c_void;
    pub fn ShSetVirtualAttributeBindings(arg1: ShHandle,
                                         arg2: *const ShBindingTable)
     -> ::libc::c_int;
    pub fn ShSetFixedAttributeBindings(arg1: ShHandle,
                                       arg2: *const ShBindingTable)
     -> ::libc::c_int;
    pub fn ShGetPhysicalAttributeBindings(arg1: ShHandle,
                                          arg2: *mut *const ShBindingTable)
     -> ::libc::c_int;
    pub fn ShExcludeAttributes(arg1: ShHandle, attributes: *mut ::libc::c_int,
                               count: ::libc::c_int) -> ::libc::c_int;
    pub fn ShGetUniformLocation(uniformMap: ShHandle,
                                name: *const ::libc::c_char) -> ::libc::c_int;
}
<commit_msg>update bindings<commit_after>#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)]
extern crate libc;
/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Copy)]
pub struct Struct_TLimits {
    pub nonInductiveForLoops: u8,
    pub whileLoops: u8,
    pub doWhileLoops: u8,
    pub generalUniformIndexing: u8,
    pub generalAttributeMatrixVectorIndexing: u8,
    pub generalVaryingIndexing: u8,
    pub generalSamplerIndexing: u8,
    pub generalVariableIndexing: u8,
    pub generalConstantMatrixVectorIndexing: u8,
}
impl ::std::clone::Clone for Struct_TLimits {
    fn clone(&self) -> Self { *self }
}
impl ::std::default::Default for Struct_TLimits {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
pub type TLimits = Struct_TLimits;
#[repr(C)]
#[derive(Copy)]
pub struct Struct_TBuiltInResource {
    pub maxLights: ::libc::c_int,
    pub maxClipPlanes: ::libc::c_int,
    pub maxTextureUnits: ::libc::c_int,
    pub maxTextureCoords: ::libc::c_int,
    pub maxVertexAttribs: ::libc::c_int,
    pub maxVertexUniformComponents: ::libc::c_int,
    pub maxVaryingFloats: ::libc::c_int,
    pub maxVertexTextureImageUnits: ::libc::c_int,
    pub maxCombinedTextureImageUnits: ::libc::c_int,
    pub maxTextureImageUnits: ::libc::c_int,
    pub maxFragmentUniformComponents: ::libc::c_int,
    pub maxDrawBuffers: ::libc::c_int,
    pub maxVertexUniformVectors: ::libc::c_int,
    pub maxVaryingVectors: ::libc::c_int,
    pub maxFragmentUniformVectors: ::libc::c_int,
    pub maxVertexOutputVectors: ::libc::c_int,
    pub maxFragmentInputVectors: ::libc::c_int,
    pub minProgramTexelOffset: ::libc::c_int,
    pub maxProgramTexelOffset: ::libc::c_int,
    pub maxClipDistances: ::libc::c_int,
    pub maxComputeWorkGroupCountX: ::libc::c_int,
    pub maxComputeWorkGroupCountY: ::libc::c_int,
    pub maxComputeWorkGroupCountZ: ::libc::c_int,
    pub maxComputeWorkGroupSizeX: ::libc::c_int,
    pub maxComputeWorkGroupSizeY: ::libc::c_int,
    pub maxComputeWorkGroupSizeZ: ::libc::c_int,
    pub maxComputeUniformComponents: ::libc::c_int,
    pub maxComputeTextureImageUnits: ::libc::c_int,
    pub maxComputeImageUniforms: ::libc::c_int,
    pub maxComputeAtomicCounters: ::libc::c_int,
    pub maxComputeAtomicCounterBuffers: ::libc::c_int,
    pub maxVaryingComponents: ::libc::c_int,
    pub maxVertexOutputComponents: ::libc::c_int,
    pub maxGeometryInputComponents: ::libc::c_int,
    pub maxGeometryOutputComponents: ::libc::c_int,
    pub maxFragmentInputComponents: ::libc::c_int,
    pub maxImageUnits: ::libc::c_int,
    pub maxCombinedImageUnitsAndFragmentOutputs: ::libc::c_int,
    pub maxCombinedShaderOutputResources: ::libc::c_int,
    pub maxImageSamples: ::libc::c_int,
    pub maxVertexImageUniforms: ::libc::c_int,
    pub maxTessControlImageUniforms: ::libc::c_int,
    pub maxTessEvaluationImageUniforms: ::libc::c_int,
    pub maxGeometryImageUniforms: ::libc::c_int,
    pub maxFragmentImageUniforms: ::libc::c_int,
    pub maxCombinedImageUniforms: ::libc::c_int,
    pub maxGeometryTextureImageUnits: ::libc::c_int,
    pub maxGeometryOutputVertices: ::libc::c_int,
    pub maxGeometryTotalOutputComponents: ::libc::c_int,
    pub maxGeometryUniformComponents: ::libc::c_int,
    pub maxGeometryVaryingComponents: ::libc::c_int,
    pub maxTessControlInputComponents: ::libc::c_int,
    pub maxTessControlOutputComponents: ::libc::c_int,
    pub maxTessControlTextureImageUnits: ::libc::c_int,
    pub maxTessControlUniformComponents: ::libc::c_int,
    pub maxTessControlTotalOutputComponents: ::libc::c_int,
    pub maxTessEvaluationInputComponents: ::libc::c_int,
    pub maxTessEvaluationOutputComponents: ::libc::c_int,
    pub maxTessEvaluationTextureImageUnits: ::libc::c_int,
    pub maxTessEvaluationUniformComponents: ::libc::c_int,
    pub maxTessPatchComponents: ::libc::c_int,
    pub maxPatchVertices: ::libc::c_int,
    pub maxTessGenLevel: ::libc::c_int,
    pub maxViewports: ::libc::c_int,
    pub maxVertexAtomicCounters: ::libc::c_int,
    pub maxTessControlAtomicCounters: ::libc::c_int,
    pub maxTessEvaluationAtomicCounters: ::libc::c_int,
    pub maxGeometryAtomicCounters: ::libc::c_int,
    pub maxFragmentAtomicCounters: ::libc::c_int,
    pub maxCombinedAtomicCounters: ::libc::c_int,
    pub maxAtomicCounterBindings: ::libc::c_int,
    pub maxVertexAtomicCounterBuffers: ::libc::c_int,
    pub maxTessControlAtomicCounterBuffers: ::libc::c_int,
    pub maxTessEvaluationAtomicCounterBuffers: ::libc::c_int,
    pub maxGeometryAtomicCounterBuffers: ::libc::c_int,
    pub maxFragmentAtomicCounterBuffers: ::libc::c_int,
    pub maxCombinedAtomicCounterBuffers: ::libc::c_int,
    pub maxAtomicCounterBufferSize: ::libc::c_int,
    pub maxTransformFeedbackBuffers: ::libc::c_int,
    pub maxTransformFeedbackInterleavedComponents: ::libc::c_int,
    pub maxCullDistances: ::libc::c_int,
    pub maxCombinedClipAndCullDistances: ::libc::c_int,
    pub maxSamples: ::libc::c_int,
    pub limits: TLimits,
}
impl ::std::clone::Clone for Struct_TBuiltInResource {
    fn clone(&self) -> Self { *self }
}
impl ::std::default::Default for Struct_TBuiltInResource {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
pub type TBuiltInResource = Struct_TBuiltInResource;
pub type Enum_EShLanguage = ::libc::c_uint;
pub const EShLangVertex: ::libc::c_uint = 0;
pub const EShLangTessControl: ::libc::c_uint = 1;
pub const EShLangTessEvaluation: ::libc::c_uint = 2;
pub const EShLangGeometry: ::libc::c_uint = 3;
pub const EShLangFragment: ::libc::c_uint = 4;
pub const EShLangCompute: ::libc::c_uint = 5;
pub const EShLangCount: ::libc::c_uint = 6;
pub type EShLanguage = Enum_EShLanguage;
pub type Enum_EShLanguageMask = ::libc::c_uint;
pub const EShLangVertexMask: ::libc::c_uint = 1;
pub const EShLangTessControlMask: ::libc::c_uint = 2;
pub const EShLangTessEvaluationMask: ::libc::c_uint = 4;
pub const EShLangGeometryMask: ::libc::c_uint = 8;
pub const EShLangFragmentMask: ::libc::c_uint = 16;
pub const EShLangComputeMask: ::libc::c_uint = 32;
pub type EShLanguageMask = Enum_EShLanguageMask;
pub type Enum_EShExecutable = ::libc::c_uint;
pub const EShExVertexFragment: ::libc::c_uint = 0;
pub const EShExFragment: ::libc::c_uint = 1;
pub type EShExecutable = Enum_EShExecutable;
pub type Enum_EShOptimizationLevel = ::libc::c_uint;
pub const EShOptNoGeneration: ::libc::c_uint = 0;
pub const EShOptNone: ::libc::c_uint = 1;
pub const EShOptSimple: ::libc::c_uint = 2;
pub const EShOptFull: ::libc::c_uint = 3;
pub type EShOptimizationLevel = Enum_EShOptimizationLevel;
pub type Enum_EShMessages = ::libc::c_uint;
pub const EShMsgDefault: ::libc::c_uint = 0;
pub const EShMsgRelaxedErrors: ::libc::c_uint = 1;
pub const EShMsgSuppressWarnings: ::libc::c_uint = 2;
pub const EShMsgAST: ::libc::c_uint = 4;
pub type EShMessages = Enum_EShMessages;
#[repr(C)]
#[derive(Copy)]
pub struct Struct_ShBinding {
    pub name: *const ::libc::c_char,
    pub binding: ::libc::c_int,
}
impl ::std::clone::Clone for Struct_ShBinding {
    fn clone(&self) -> Self { *self }
}
impl ::std::default::Default for Struct_ShBinding {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
pub type ShBinding = Struct_ShBinding;
#[repr(C)]
#[derive(Copy)]
pub struct Struct_ShBindingTable {
    pub numBindings: ::libc::c_int,
    pub bindings: *mut ShBinding,
}
impl ::std::clone::Clone for Struct_ShBindingTable {
    fn clone(&self) -> Self { *self }
}
impl ::std::default::Default for Struct_ShBindingTable {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
pub type ShBindingTable = Struct_ShBindingTable;
pub type ShHandle = *mut ::libc::c_void;
extern "C" {
    pub fn ShInitialize() -> ::libc::c_int;
    pub fn ShFinalize() -> ::libc::c_int;
    pub fn StageName(arg1: EShLanguage) -> *const ::libc::c_char;
    pub fn ShConstructCompiler(arg1: EShLanguage, debugOptions: ::libc::c_int)
     -> ShHandle;
    pub fn ShConstructLinker(arg1: EShExecutable, debugOptions: ::libc::c_int)
     -> ShHandle;
    pub fn ShConstructUniformMap() -> ShHandle;
    pub fn ShDestruct(arg1: ShHandle) -> ();
    pub fn ShCompile(arg1: ShHandle,
                     shaderStrings: *const *const ::libc::c_char,
                     numStrings: ::libc::c_int, lengths: *const ::libc::c_int,
                     arg2: EShOptimizationLevel,
                     resources: *const TBuiltInResource,
                     debugOptions: ::libc::c_int,
                     defaultVersion: ::libc::c_int, forwardCompatible: u8,
                     messages: EShMessages) -> ::libc::c_int;
    pub fn ShLink(arg1: ShHandle, h: *const ShHandle,
                  numHandles: ::libc::c_int, uniformMap: ShHandle,
                  uniformsAccessed: *mut *mut ::libc::c_short,
                  numUniformsAccessed: *mut ::libc::c_int) -> ::libc::c_int;
    pub fn ShLinkExt(arg1: ShHandle, h: *const ShHandle,
                     numHandles: ::libc::c_int) -> ::libc::c_int;
    pub fn ShSetEncryptionMethod(arg1: ShHandle) -> ();
    pub fn ShGetInfoLog(arg1: ShHandle) -> *const ::libc::c_char;
    pub fn ShGetExecutable(arg1: ShHandle) -> *const ::libc::c_void;
    pub fn ShSetVirtualAttributeBindings(arg1: ShHandle,
                                         arg2: *const ShBindingTable)
     -> ::libc::c_int;
    pub fn ShSetFixedAttributeBindings(arg1: ShHandle,
                                       arg2: *const ShBindingTable)
     -> ::libc::c_int;
    pub fn ShGetPhysicalAttributeBindings(arg1: ShHandle,
                                          arg2: *mut *const ShBindingTable)
     -> ::libc::c_int;
    pub fn ShExcludeAttributes(arg1: ShHandle, attributes: *mut ::libc::c_int,
                               count: ::libc::c_int) -> ::libc::c_int;
    pub fn ShGetUniformLocation(uniformMap: ShHandle,
                                name: *const ::libc::c_char) -> ::libc::c_int;
}
<|endoftext|>


<commit_before>#![feature(custom_derive)]
#![feature(concat_idents)]
#![feature(alloc)]
#![feature(step_by)]
#![feature(test)]

extern crate alloc;
extern crate num;

#[cfg(test)]
extern crate test;
mod raw;
mod types;
pub use raw::*;
pub use types::*;

#[cfg(test)]
mod tests {
    macro_rules! bench_test {
        ($(($m: ident, $nbits: ident, $storage: ident)),*) => {
            mod get {
                $(
                    mod $m {
                        use super::super::super::*;
                        use test::{self, Bencher};
                        #[bench]
                        fn get(b: &mut Bencher) {
                            let n = test::black_box(100);
                            let mut vec: NbitsVec<$nbits, $storage> = NbitsVec::with_capacity(n);
                            unsafe { vec.set_len(n) }
                            for i in 0..n {
                                vec.set(i, i as u64);
                            }
                            b.iter(|| {
                                (0..n).fold(0, |_a, i| vec.get(i));
                            })
                        }
                    }
                )*
            }
            /*
            mod set {
                $(
                    mod $m {
                        use super::super::super::*;
                        use test::{self, Bencher};
                        #[bench]
                        fn set(b: &mut Bencher) {
                            b.iter(|| {
                                let n = test::black_box(100);
                                let mut vec: NbitsVec<As1bits> = NbitsVec::with_capacity(n);
                                unsafe { vec.set_len(n) };
                                for i in 0..n {
                                    vec.set(i, i as u64);
                                }
                            });
                        }
                    }
                )*
            }
            */
            /*
            mod fill {
                $(
                    mod $m {
                        use super::super::super::*;
                        use test::{self, Bencher};
                        #[bench]
                        fn bench(b: &mut Bencher) {
                            b.iter(|| {
                                let n = test::black_box(100);
                                let mut vec: NbitsVec<As1bits> = NbitsVec::with_capacity(n);
                                unsafe { vec.set_len(n) };
                                vec.fill_bits(0, n, false);
                            });
                        }
                    }
                )*
            }
            mod set_bit_by_bit {
                $(
                    mod $m {
                        use super::super::super::*;
                        use test::{self, Bencher};
                        #[bench]
                        fn bench(b: &mut Bencher) {
                            b.iter(|| {
                                let n = test::black_box(100);
                                let mut vec: NbitsVec<As1bits> = NbitsVec::with_capacity(n);
                                unsafe { vec.set_len(n) };
                                for i in 0..n {
                                    vec.set_bit_by_bit(i, i as u64);
                                }
                            });
                        }
                    }
                )*
            }
            */
        }
    }
    bench_test! {
        (test_4bits_usize, As4bits, usize),
        (test_4bits_u64, As4bits, u64),
        (test_4bits_u32, As4bits, u32),
        (test_4bits_u16, As4bits, u16),
        (test_4bits_u8, As4bits, u8),
        (test_3bits_usize, As3bits, usize),
        (test_3bits_u64, As3bits, u64),
        (test_3bits_u32, As3bits, u32),
        (test_3bits_u16, As3bits, u16),
        (test_3bits_u8, As3bits, u8),
        (test_2bits_usize, As2bits, usize),
        (test_2bits_u64, As2bits, u64),
        (test_2bits_u32, As2bits, u32),
        (test_2bits_u16, As2bits, u16),
        (test_2bits_u8, As2bits, u8),
        (test_1bits_usize, As1bits, usize),
        (test_1bits_u64, As1bits, u64),
        (test_1bits_u32, As1bits, u32),
        (test_1bits_u16, As1bits, u16),
        (test_1bits_u8, As1bits, u8)
    }
}
<commit_msg>Increase test vector size.<commit_after>#![feature(custom_derive)]
#![feature(concat_idents)]
#![feature(alloc)]
#![feature(step_by)]
#![feature(test)]

extern crate alloc;
extern crate num;

#[cfg(test)]
extern crate test;
mod raw;
mod types;
pub use raw::*;
pub use types::*;

#[cfg(test)]
mod tests {
    macro_rules! bench_test {
        ($(($m: ident, $nbits: ident, $storage: ident)),*) => {
            mod get {
                $(
                    mod $m {
                        use super::super::super::*;
                        use test::{self, Bencher};
                        #[bench]
                        fn get(b: &mut Bencher) {
                            let n = test::black_box(1000);
                            let mut vec: NbitsVec<$nbits, $storage> = NbitsVec::with_capacity(n);
                            unsafe { vec.set_len(n) }
                            b.iter(|| {
                                (0..n).fold(0, |_a, i| vec.get(i));
                            })
                        }
                    }
                )*
            }
            /*
            mod set {
                $(
                    mod $m {
                        use super::super::super::*;
                        use test::{self, Bencher};
                        #[bench]
                        fn set(b: &mut Bencher) {
                            b.iter(|| {
                                let n = test::black_box(100);
                                let mut vec: NbitsVec<As1bits> = NbitsVec::with_capacity(n);
                                unsafe { vec.set_len(n) };
                                for i in 0..n {
                                    vec.set(i, i as u64);
                                }
                            });
                        }
                    }
                )*
            }
            */
            /*
            mod fill {
                $(
                    mod $m {
                        use super::super::super::*;
                        use test::{self, Bencher};
                        #[bench]
                        fn bench(b: &mut Bencher) {
                            b.iter(|| {
                                let n = test::black_box(100);
                                let mut vec: NbitsVec<As1bits> = NbitsVec::with_capacity(n);
                                unsafe { vec.set_len(n) };
                                vec.fill_bits(0, n, false);
                            });
                        }
                    }
                )*
            }
            mod set_bit_by_bit {
                $(
                    mod $m {
                        use super::super::super::*;
                        use test::{self, Bencher};
                        #[bench]
                        fn bench(b: &mut Bencher) {
                            b.iter(|| {
                                let n = test::black_box(100);
                                let mut vec: NbitsVec<As1bits> = NbitsVec::with_capacity(n);
                                unsafe { vec.set_len(n) };
                                for i in 0..n {
                                    vec.set_bit_by_bit(i, i as u64);
                                }
                            });
                        }
                    }
                )*
            }
            */
        }
    }
    bench_test! {
        (test_4bits_usize, As4bits, usize),
        (test_4bits_u64, As4bits, u64),
        (test_4bits_u32, As4bits, u32),
        (test_4bits_u16, As4bits, u16),
        (test_4bits_u8, As4bits, u8),
        (test_3bits_usize, As3bits, usize),
        (test_3bits_u64, As3bits, u64),
        (test_3bits_u32, As3bits, u32),
        (test_3bits_u16, As3bits, u16),
        (test_3bits_u8, As3bits, u8),
        (test_2bits_usize, As2bits, usize),
        (test_2bits_u64, As2bits, u64),
        (test_2bits_u32, As2bits, u32),
        (test_2bits_u16, As2bits, u16),
        (test_2bits_u8, As2bits, u8),
        (test_1bits_usize, As1bits, usize),
        (test_1bits_u64, As1bits, u64),
        (test_1bits_u32, As1bits, u32),
        (test_1bits_u16, As1bits, u16),
        (test_1bits_u8, As1bits, u8)
    }
}
<|endoftext|>


<commit_before>#![feature(const_fn)]
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]

extern crate serde;
extern crate serde_json;

use serde::Deserialize;
use std::fmt;
use std::io::{self, Read};
use std::convert;
use std::collections::HashMap;
use std::net::{
    TcpListener,
    TcpStream,
    SocketAddr,
    ToSocketAddrs,
};
use std::sync::{
    self,
    Mutex,
    Arc,
};
use std::sync::mpsc::{
    channel,
    Sender,
    TryRecvError,
};
use std::thread::{
    self,
    JoinHandle,
};

#[derive(Debug)]
pub enum Error {
    Io(io::Error),
    Json(serde_json::Error),
    Sender,
    Unimplemented,
}

impl convert::From<serde_json::Error> for Error {
    fn from(err: serde_json::Error) -> Error {
        match err {
            serde_json::Error::IoError(err) => Error::Io(err),
            err => Error::Json(err),
        }
    }
}

impl convert::From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

impl<T> convert::From<sync::mpsc::SendError<T>> for Error {
    fn from(_: sync::mpsc::SendError<T>) -> Error {
        Error::Sender
    }
}

pub type Result<T> = std::result::Result<T, Error>;

fn handle_conn<F, Request, Reply>(stream: TcpStream, f: F) -> Result<()>
    where Request: 'static + fmt::Debug + Send + serde::de::Deserialize + serde::ser::Serialize,
          Reply: 'static + fmt::Debug + serde::ser::Serialize,
          F: 'static + Clone + Serve<Request, Reply>
{
    let read_stream = try!(stream.try_clone());
    let mut de = serde_json::Deserializer::new(read_stream.bytes());
    let stream = Arc::new(Mutex::new(stream));
    loop {
        let request_packet: Packet<Request> = try!(Packet::deserialize(&mut de));
        match request_packet {
            Packet::Shutdown => {
                let stream = stream.clone();
                let mut my_stream = stream.lock().unwrap();
                try!(serde_json::to_writer(&mut *my_stream, &request_packet));
                break;
            },
            Packet::Message(id, message) => {
                let f = f.clone();
                let arc_stream = stream.clone();
                thread::spawn(move || {
                    let reply = f.serve(message);
                    let reply_packet = Packet::Message(id, reply);
                    let mut my_stream = arc_stream.lock().unwrap();
                    serde_json::to_writer(&mut *my_stream, &reply_packet).unwrap();
                });
            },
        }
    }
    Ok(())
}

pub struct Shutdown {
    tx: Sender<()>,
    join_handle: JoinHandle<()>,
    addr: SocketAddr,
}

impl Shutdown {
    pub fn wait(self) {
        self.join_handle.join().unwrap();
    }

    pub fn shutdown(self) {
        self.tx.send(()).expect(&line!().to_string());
        TcpStream::connect(&self.addr).unwrap();
        self.join_handle.join().expect(&line!().to_string());
    }
}

pub fn serve_async<A, F, Request, Reply>(addr: A, f: F) -> io::Result<Shutdown>
    where A: ToSocketAddrs,
          Request: 'static + fmt::Debug + Send + serde::de::Deserialize + fmt::Debug + serde::ser::Serialize,
          Reply: 'static + fmt::Debug + serde::ser::Serialize,
          F: 'static + Clone + Serve<Request, Reply>,
{
    let addr = addr.to_socket_addrs().unwrap().next().unwrap();
    let listener = try!(TcpListener::bind(addr.clone()));
    let (die_tx, die_rx) = channel();
    let join_handle = thread::spawn(move || {
        for conn in listener.incoming() {
            match die_rx.try_recv() {
                Ok(_) => break,
                Err(TryRecvError::Disconnected) => {
                    println!("serve: sender disconnected ");
                    break;
                },
                _ => (),
            }
            let conn = match conn {
                Err(err) => {
                    println!("I couldn't unwrap the connection :( {:?}", err);
                    return;
                },
                Ok(c) => c,
            };
            let f = f.clone();
            thread::spawn(move || {
                if let Err(err) = handle_conn(conn, f) {
                    println!("error handling connection: {:?}", err);
                }
            });
        }
    });
    Ok(Shutdown{
        tx: die_tx,
        join_handle: join_handle,
        addr: addr.clone(),
    })
}

pub trait Serve<Request, Reply>: Send + Sync {
    fn serve(&self, request: Request) -> Reply;
}

impl<Request, Reply, S> Serve<Request, Reply> for Arc<S>
    where S: Serve<Request, Reply>
{
    fn serve(&self, request: Request) -> Reply {
        S::serve(self, request)
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
enum Packet<T> {
    Message(u64, T),
    Shutdown,
}

fn reader<Reply>(
    stream: TcpStream,
    requests: Arc<Mutex<HashMap<u64, Sender<Reply>>>>)
    where Reply: serde::Deserialize
{
    let mut de = serde_json::Deserializer::new(stream.bytes());
    loop {
        match Packet::deserialize(&mut de) {
            Ok(Packet::Message(id, reply)) => {
                let mut requests = requests.lock().unwrap();
                let reply_tx = requests.remove(&id).unwrap();
                reply_tx.send(reply).unwrap();
            },
            Ok(Packet::Shutdown) => {
                break;
            }
            // TODO: This shutdown logic is janky.. What's the right way to do this?
            Err(err) => panic!("unexpected error while parsing!: {:?}", err),
        }
    }
}

fn increment(cur_id: &mut u64) -> u64 {
    let id = *cur_id;
    *cur_id += 1;
    id
}

struct SyncedClientState {
    next_id: u64,
    stream: TcpStream,
}

pub struct Client<Request, Reply>
    where Request: serde::ser::Serialize
{
    synced_state: Mutex<SyncedClientState>,
    requests: Arc<Mutex<HashMap<u64, Sender<Reply>>>>,
    reader_guard: Option<thread::JoinHandle<()>>,
    _request: std::marker::PhantomData<Request>,
}

impl<Request, Reply> Client<Request, Reply>
    where Reply: serde::de::Deserialize + Send + 'static,
          Request: serde::ser::Serialize
{
    pub fn new(stream: TcpStream) -> io::Result<Self> {
        let requests = Arc::new(Mutex::new(HashMap::new()));
        let reader_stream = try!(stream.try_clone());
        let reader_requests = requests.clone();
        let reader_guard =
            thread::spawn(move || reader(reader_stream, reader_requests));
        Ok(Client{
            synced_state: Mutex::new(SyncedClientState{
                next_id: 0,
                stream: stream,
            }),
            requests: requests,
            reader_guard: Some(reader_guard),
            _request: std::marker::PhantomData,
        })
    }

    pub fn rpc(&self, request: &Request) -> Result<Reply>
        where Request: serde::ser::Serialize + Send + 'static
    {
        let (tx, rx) = channel();
        let mut state = self.synced_state.lock().unwrap();
        let id = increment(&mut state.next_id);
        {
            let mut requests = self.requests.lock().unwrap();
            requests.insert(id, tx);
        }
        let packet = Packet::Message(id, request);
        try!(serde_json::to_writer(&mut state.stream, &packet));
        drop(state);
        Ok(rx.recv().unwrap())
    }
}

impl<Request, Reply> Drop for Client<Request, Reply>
    where Request: serde::ser::Serialize
{
    fn drop(&mut self) {
        {
            let mut state = self.synced_state.lock().unwrap();
            let packet: Packet<Request> = Packet::Shutdown;
            if let Err(err) = serde_json::to_writer(&mut state.stream, &packet) {
                println!("WARN: while disconnecting client from server: {:?}", err);
            }
        }
        self.reader_guard.take().unwrap().join().unwrap();
    }
}

#[cfg(test)]
mod test {
    use serde;
    use super::*;
    use std::fmt;
    use std::io;
    use std::net::{TcpStream, SocketAddr, ToSocketAddrs};
    use std::sync::{Arc, Mutex, Barrier};
    use std::sync::atomic::{AtomicUsize, Ordering};
    use std::thread;

    const PORT: AtomicUsize = AtomicUsize::new(10000);

    fn next_addr() -> SocketAddr {
        let addr = format!("127.0.0.1:{}", PORT.fetch_add(1, Ordering::SeqCst));
        addr.to_socket_addrs().unwrap().next().unwrap()
    }

    #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
    enum Request {
        Increment
    }

    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    enum Reply {
        Increment(u64)
    }

    struct Server {
        counter: Mutex<u64>,
    }

    impl Serve<Request, Reply> for Server {
        fn serve(&self, _: Request) -> Reply {
            let mut counter = self.counter.lock().unwrap();
            let reply = Reply::Increment(*counter);
            *counter += 1;
            reply
        }
    }

    impl Server {
        fn new() -> Server {
            Server{counter: Mutex::new(0)}
        }

        fn count(&self) -> u64 {
            *self.counter.lock().unwrap()
        }
    }

    fn wtf<F, Request, Reply>(server: F) -> (SocketAddr, Shutdown)
        where Request: 'static + fmt::Debug + Send + serde::de::Deserialize + fmt::Debug + serde::ser::Serialize,
              Reply: 'static + fmt::Debug + Send + serde::ser::Serialize,
              F: 'static + Clone + Serve<Request, Reply>
    {
        let mut addr;
        let mut shutdown;
        while let &Err(_) = {shutdown = serve_async({addr = next_addr(); &addr}, server.clone()); &shutdown} { }
        (addr, shutdown.unwrap())
    }

    #[test]
    fn test_handle() {
        let server = Arc::new(Server::new());
        let (addr, shutdown) = wtf(server.clone());
        let client_stream = TcpStream::connect(&addr).unwrap();
        let client: Client<Reply> = Client::new(client_stream).expect(&line!().to_string());
        client.disconnect::<Request>().unwrap();
        shutdown.shutdown();
    }

    #[test]
    fn test() {
        let server = Arc::new(Server::new());
        let (addr, shutdown) = wtf(server.clone());
        let client_stream = TcpStream::connect(&addr).unwrap();
        let client = Client::new(client_stream).unwrap();
        assert_eq!(Reply::Increment(0), client.rpc(&Request::Increment).unwrap());
        assert_eq!(1, server.count());
        assert_eq!(Reply::Increment(1), client.rpc(&Request::Increment).unwrap());
        assert_eq!(2, server.count());
        client.disconnect::<Request>().unwrap();
        shutdown.shutdown();
    }

    struct BarrierServer {
        barrier: Barrier,
        inner: Server,
    }

    impl Serve<Request, Reply> for BarrierServer {
        fn serve(&self, request: Request) -> Reply {
            self.barrier.wait();
            let reply = try!(self.inner.serve(request));
            Ok(reply)
        }
    }

    impl BarrierServer {
        fn new(n: usize) -> BarrierServer {
            BarrierServer{barrier: Barrier::new(n), inner: Server::new()}
        }

        fn count(&self) -> u64 {
            self.inner.count()
        }
    }

    #[test]
    fn test_concurrent() {
        let server = Arc::new(BarrierServer::new(10));
        let (addr, shutdown) = wtf(server.clone());
        let client_stream = TcpStream::connect(&addr).unwrap();
        let client: Arc<Client<Reply>> = Arc::new(Client::new(client_stream).unwrap());
        let mut join_handles = vec![];
        for _ in 0..10 {
            let my_client = client.clone();
            join_handles.push(thread::spawn(move || my_client.rpc(&Request::Increment).unwrap()));
        }
        for handle in join_handles.into_iter() {
            handle.join().unwrap();
        }
        assert_eq!(10, server.count());
        let client = match Arc::try_unwrap(client) {
            Err(_) => panic!("couldn't unwrap arc"),
            Ok(c) => c,
        };
        client.disconnect::<Request>().unwrap();
        shutdown.shutdown();
    }
}
<commit_msg>Fix failing tests<commit_after>#![feature(const_fn)]
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]

extern crate serde;
extern crate serde_json;

use serde::Deserialize;
use std::fmt;
use std::io::{self, Read};
use std::convert;
use std::collections::HashMap;
use std::net::{
    TcpListener,
    TcpStream,
    SocketAddr,
    ToSocketAddrs,
};
use std::sync::{
    self,
    Mutex,
    Arc,
};
use std::sync::mpsc::{
    channel,
    Sender,
    TryRecvError,
};
use std::thread::{
    self,
    JoinHandle,
};

#[derive(Debug)]
pub enum Error {
    Io(io::Error),
    Json(serde_json::Error),
    Sender,
    Unimplemented,
}

impl convert::From<serde_json::Error> for Error {
    fn from(err: serde_json::Error) -> Error {
        match err {
            serde_json::Error::IoError(err) => Error::Io(err),
            err => Error::Json(err),
        }
    }
}

impl convert::From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

impl<T> convert::From<sync::mpsc::SendError<T>> for Error {
    fn from(_: sync::mpsc::SendError<T>) -> Error {
        Error::Sender
    }
}

pub type Result<T> = std::result::Result<T, Error>;

fn handle_conn<F, Request, Reply>(stream: TcpStream, f: F) -> Result<()>
    where Request: 'static + fmt::Debug + Send + serde::de::Deserialize + serde::ser::Serialize,
          Reply: 'static + fmt::Debug + serde::ser::Serialize,
          F: 'static + Clone + Serve<Request, Reply>
{
    let read_stream = try!(stream.try_clone());
    let mut de = serde_json::Deserializer::new(read_stream.bytes());
    let stream = Arc::new(Mutex::new(stream));
    loop {
        let request_packet: Packet<Request> = try!(Packet::deserialize(&mut de));
        match request_packet {
            Packet::Shutdown => {
                let stream = stream.clone();
                let mut my_stream = stream.lock().unwrap();
                try!(serde_json::to_writer(&mut *my_stream, &request_packet));
                break;
            },
            Packet::Message(id, message) => {
                let f = f.clone();
                let arc_stream = stream.clone();
                thread::spawn(move || {
                    let reply = f.serve(message);
                    let reply_packet = Packet::Message(id, reply);
                    let mut my_stream = arc_stream.lock().unwrap();
                    serde_json::to_writer(&mut *my_stream, &reply_packet).unwrap();
                });
            },
        }
    }
    Ok(())
}

pub struct Shutdown {
    tx: Sender<()>,
    join_handle: JoinHandle<()>,
    addr: SocketAddr,
}

impl Shutdown {
    pub fn wait(self) {
        self.join_handle.join().unwrap();
    }

    pub fn shutdown(self) {
        self.tx.send(()).expect(&line!().to_string());
        TcpStream::connect(&self.addr).unwrap();
        self.join_handle.join().expect(&line!().to_string());
    }
}

pub fn serve_async<A, F, Request, Reply>(addr: A, f: F) -> io::Result<Shutdown>
    where A: ToSocketAddrs,
          Request: 'static + fmt::Debug + Send + serde::de::Deserialize + fmt::Debug + serde::ser::Serialize,
          Reply: 'static + fmt::Debug + serde::ser::Serialize,
          F: 'static + Clone + Serve<Request, Reply>,
{
    let addr = addr.to_socket_addrs().unwrap().next().unwrap();
    let listener = try!(TcpListener::bind(addr.clone()));
    let (die_tx, die_rx) = channel();
    let join_handle = thread::spawn(move || {
        for conn in listener.incoming() {
            match die_rx.try_recv() {
                Ok(_) => break,
                Err(TryRecvError::Disconnected) => {
                    println!("serve: sender disconnected ");
                    break;
                },
                _ => (),
            }
            let conn = match conn {
                Err(err) => {
                    println!("I couldn't unwrap the connection :( {:?}", err);
                    return;
                },
                Ok(c) => c,
            };
            let f = f.clone();
            thread::spawn(move || {
                if let Err(err) = handle_conn(conn, f) {
                    println!("error handling connection: {:?}", err);
                }
            });
        }
    });
    Ok(Shutdown{
        tx: die_tx,
        join_handle: join_handle,
        addr: addr.clone(),
    })
}

pub trait Serve<Request, Reply>: Send + Sync {
    fn serve(&self, request: Request) -> Reply;
}

impl<Request, Reply, S> Serve<Request, Reply> for Arc<S>
    where S: Serve<Request, Reply>
{
    fn serve(&self, request: Request) -> Reply {
        S::serve(self, request)
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
enum Packet<T> {
    Message(u64, T),
    Shutdown,
}

fn reader<Reply>(
    stream: TcpStream,
    requests: Arc<Mutex<HashMap<u64, Sender<Reply>>>>)
    where Reply: serde::Deserialize
{
    let mut de = serde_json::Deserializer::new(stream.bytes());
    loop {
        match Packet::deserialize(&mut de) {
            Ok(Packet::Message(id, reply)) => {
                let mut requests = requests.lock().unwrap();
                let reply_tx = requests.remove(&id).unwrap();
                reply_tx.send(reply).unwrap();
            },
            Ok(Packet::Shutdown) => {
                break;
            }
            // TODO: This shutdown logic is janky.. What's the right way to do this?
            Err(err) => panic!("unexpected error while parsing!: {:?}", err),
        }
    }
}

fn increment(cur_id: &mut u64) -> u64 {
    let id = *cur_id;
    *cur_id += 1;
    id
}

struct SyncedClientState {
    next_id: u64,
    stream: TcpStream,
}

pub struct Client<Request, Reply>
    where Request: serde::ser::Serialize
{
    synced_state: Mutex<SyncedClientState>,
    requests: Arc<Mutex<HashMap<u64, Sender<Reply>>>>,
    reader_guard: Option<thread::JoinHandle<()>>,
    _request: std::marker::PhantomData<Request>,
}

impl<Request, Reply> Client<Request, Reply>
    where Reply: serde::de::Deserialize + Send + 'static,
          Request: serde::ser::Serialize
{
    pub fn new(stream: TcpStream) -> io::Result<Self> {
        let requests = Arc::new(Mutex::new(HashMap::new()));
        let reader_stream = try!(stream.try_clone());
        let reader_requests = requests.clone();
        let reader_guard =
            thread::spawn(move || reader(reader_stream, reader_requests));
        Ok(Client{
            synced_state: Mutex::new(SyncedClientState{
                next_id: 0,
                stream: stream,
            }),
            requests: requests,
            reader_guard: Some(reader_guard),
            _request: std::marker::PhantomData,
        })
    }

    pub fn rpc(&self, request: &Request) -> Result<Reply>
        where Request: serde::ser::Serialize + Send + 'static
    {
        let (tx, rx) = channel();
        let mut state = self.synced_state.lock().unwrap();
        let id = increment(&mut state.next_id);
        {
            let mut requests = self.requests.lock().unwrap();
            requests.insert(id, tx);
        }
        let packet = Packet::Message(id, request);
        try!(serde_json::to_writer(&mut state.stream, &packet));
        drop(state);
        Ok(rx.recv().unwrap())
    }
}

impl<Request, Reply> Drop for Client<Request, Reply>
    where Request: serde::ser::Serialize
{
    fn drop(&mut self) {
        {
            let mut state = self.synced_state.lock().unwrap();
            let packet: Packet<Request> = Packet::Shutdown;
            if let Err(err) = serde_json::to_writer(&mut state.stream, &packet) {
                println!("WARN: while disconnecting client from server: {:?}", err);
            }
        }
        self.reader_guard.take().unwrap().join().unwrap();
    }
}

#[cfg(test)]
mod test {
    use serde;
    use super::*;
    use std::fmt;
    use std::net::{TcpStream, SocketAddr, ToSocketAddrs};
    use std::sync::{Arc, Mutex, Barrier};
    use std::sync::atomic::{AtomicUsize, Ordering};
    use std::thread;

    const PORT: AtomicUsize = AtomicUsize::new(10000);

    fn next_addr() -> SocketAddr {
        let addr = format!("127.0.0.1:{}", PORT.fetch_add(1, Ordering::SeqCst));
        addr.to_socket_addrs().unwrap().next().unwrap()
    }

    #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
    enum Request {
        Increment
    }

    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    enum Reply {
        Increment(u64)
    }

    struct Server {
        counter: Mutex<u64>,
    }

    impl Serve<Request, Reply> for Server {
        fn serve(&self, _: Request) -> Reply {
            let mut counter = self.counter.lock().unwrap();
            let reply = Reply::Increment(*counter);
            *counter += 1;
            reply
        }
    }

    impl Server {
        fn new() -> Server {
            Server{counter: Mutex::new(0)}
        }

        fn count(&self) -> u64 {
            *self.counter.lock().unwrap()
        }
    }

    fn wtf<F, Request, Reply>(server: F) -> (SocketAddr, Shutdown)
        where Request: 'static + fmt::Debug + Send + serde::de::Deserialize + fmt::Debug + serde::ser::Serialize,
              Reply: 'static + fmt::Debug + Send + serde::ser::Serialize,
              F: 'static + Clone + Serve<Request, Reply>
    {
        let mut addr;
        let mut shutdown;
        while let &Err(_) = {shutdown = serve_async({addr = next_addr(); &addr}, server.clone()); &shutdown} { }
        (addr, shutdown.unwrap())
    }

    #[test]
    fn test_handle() {
        let server = Arc::new(Server::new());
        let (addr, shutdown) = wtf(server.clone());
        let client_stream = TcpStream::connect(&addr).unwrap();
        let client: Client<Request, Reply> = Client::new(client_stream).expect(&line!().to_string());
        drop(client);
        shutdown.shutdown();
    }

    #[test]
    fn test() {
        let server = Arc::new(Server::new());
        let (addr, shutdown) = wtf(server.clone());
        let client_stream = TcpStream::connect(&addr).unwrap();
        let client = Client::new(client_stream).unwrap();
        assert_eq!(Reply::Increment(0), client.rpc(&Request::Increment).unwrap());
        assert_eq!(1, server.count());
        assert_eq!(Reply::Increment(1), client.rpc(&Request::Increment).unwrap());
        assert_eq!(2, server.count());
        drop(client);
        shutdown.shutdown();
    }

    struct BarrierServer {
        barrier: Barrier,
        inner: Server,
    }

    impl Serve<Request, Reply> for BarrierServer {
        fn serve(&self, request: Request) -> Reply {
            self.barrier.wait();
            self.inner.serve(request)
        }
    }

    impl BarrierServer {
        fn new(n: usize) -> BarrierServer {
            BarrierServer{barrier: Barrier::new(n), inner: Server::new()}
        }

        fn count(&self) -> u64 {
            self.inner.count()
        }
    }

    #[test]
    fn test_concurrent() {
        let server = Arc::new(BarrierServer::new(10));
        let (addr, shutdown) = wtf(server.clone());
        let client_stream = TcpStream::connect(&addr).unwrap();
        let client: Arc<Client<Request, Reply>> = Arc::new(Client::new(client_stream).unwrap());
        let mut join_handles = vec![];
        for _ in 0..10 {
            let my_client = client.clone();
            join_handles.push(thread::spawn(move || my_client.rpc(&Request::Increment).unwrap()));
        }
        for handle in join_handles.into_iter() {
            handle.join().unwrap();
        }
        assert_eq!(10, server.count());
        let client = match Arc::try_unwrap(client) {
            Err(_) => panic!("couldn't unwrap arc"),
            Ok(c) => c,
        };
        drop(client);
        shutdown.shutdown();
    }
}
<|endoftext|>


<commit_before>#![feature(plugin_registrar, quote)]
#![deny(missing_docs, warnings)]

//! Stainless is a lightweight, flexible, unopinionated testing framework.
//!
//! ## Example
//!
//! ```ignore
//! describe! stainless {
//!     before_each {
//!         // Start up a test.
//!         let mut stainless = true;
//!     }
//!
//!     it "makes organizing tests easy" {
//!         // Do the test.
//!         assert!(stainless);
//!     }
//!
//!     after_each {
//!         // End the test.
//!         stainless = false;
//!     }
//!
//!     describe! nesting {
//!         it "makes it simple to categorize tests" {
//!             // It even generates submodules!
//!             assert_eq!(2u, 2u);
//!         }
//!     }
//! }
//! ```
//!
//! Expands to (roughly):
//!
//! ```rust
//! mod stainless {
//!     #[test]
//!     fn makes_organizing_tests_easy() {
//!         let mut stainless = true;
//!         assert!(stainless);
//!         stainless = false;
//!     }
//!
//!     mod nesting {
//!         #[test]
//!         fn makes_it_simple_to_categorize_tests() {
//!             assert_eq!(2u, 2u);
//!         }
//!     }
//! }
//! ```
//!
//! Stainless exports the `describe!` syntax extension, which allows
//! you to quickly generate complex testing hierarchies and reduce
//! boilerplate through `before_each` and `after_each`.
//!
//! Stainless currently supports 4 types of subblocks:
//!  - `before_each` and `after_each`,
//!  - `it` and `failing`
//!  - `bench`
//!  - nested `describe!`
//!
//! `before_each` and `after_each` allow you to group common initialization
//! and teardown for a group of tests into a single block, shortening your
//! tests.
//!
//! `it` generates tests which use `before_each` and `after_each`. `failing`
//! does the same, except the generated tests are marked with `#[should_fail]`.
//!
//! `bench` allows you to generate benchmarks in the same fashion, though
//! `before_each` and `after_each` blocks do not affect `bench` blocks.
//!
//! Nested `describe!` blocks allow you to better organize your tests into
//! small units and gives you granular control over where `before_each` and
//! `after_each` apply.
//!
//! Together, these 3 types of subblocks give you more flexibility and control
//! than the built in testing infrastructure.
//!

extern crate syntax;
extern crate rustc;

use self::describe::describe;
use rustc::plugin;
use syntax::parse::token;

mod describe;
mod parse;
mod test;
mod bench;
mod generate;

#[plugin_registrar]
#[doc(hidden)]
pub fn plugin_registrar(reg: &mut plugin::Registry) {
    reg.register_syntax_extension(token::intern("describe"), syntax::ext::base::IdentTT(box describe, None));
}

<commit_msg>(fix) Update for latest rust gates.<commit_after>#![allow(unstable)]
#![feature(plugin_registrar, quote)]
#![deny(missing_docs, warnings)]

//! Stainless is a lightweight, flexible, unopinionated testing framework.
//!
//! ## Example
//!
//! ```ignore
//! describe! stainless {
//!     before_each {
//!         // Start up a test.
//!         let mut stainless = true;
//!     }
//!
//!     it "makes organizing tests easy" {
//!         // Do the test.
//!         assert!(stainless);
//!     }
//!
//!     after_each {
//!         // End the test.
//!         stainless = false;
//!     }
//!
//!     describe! nesting {
//!         it "makes it simple to categorize tests" {
//!             // It even generates submodules!
//!             assert_eq!(2u, 2u);
//!         }
//!     }
//! }
//! ```
//!
//! Expands to (roughly):
//!
//! ```rust
//! mod stainless {
//!     #[test]
//!     fn makes_organizing_tests_easy() {
//!         let mut stainless = true;
//!         assert!(stainless);
//!         stainless = false;
//!     }
//!
//!     mod nesting {
//!         #[test]
//!         fn makes_it_simple_to_categorize_tests() {
//!             assert_eq!(2u, 2u);
//!         }
//!     }
//! }
//! ```
//!
//! Stainless exports the `describe!` syntax extension, which allows
//! you to quickly generate complex testing hierarchies and reduce
//! boilerplate through `before_each` and `after_each`.
//!
//! Stainless currently supports 4 types of subblocks:
//!  - `before_each` and `after_each`,
//!  - `it` and `failing`
//!  - `bench`
//!  - nested `describe!`
//!
//! `before_each` and `after_each` allow you to group common initialization
//! and teardown for a group of tests into a single block, shortening your
//! tests.
//!
//! `it` generates tests which use `before_each` and `after_each`. `failing`
//! does the same, except the generated tests are marked with `#[should_fail]`.
//!
//! `bench` allows you to generate benchmarks in the same fashion, though
//! `before_each` and `after_each` blocks do not affect `bench` blocks.
//!
//! Nested `describe!` blocks allow you to better organize your tests into
//! small units and gives you granular control over where `before_each` and
//! `after_each` apply.
//!
//! Together, these 3 types of subblocks give you more flexibility and control
//! than the built in testing infrastructure.
//!

extern crate syntax;
extern crate rustc;

use self::describe::describe;
use rustc::plugin;
use syntax::parse::token;

mod describe;
mod parse;
mod test;
mod bench;
mod generate;

#[plugin_registrar]
#[doc(hidden)]
pub fn plugin_registrar(reg: &mut plugin::Registry) {
    reg.register_syntax_extension(
        token::intern("describe"),
        syntax::ext::base::IdentTT(Box::new(describe), None)
    );
}

<|endoftext|>