<commit_before>extern crate fruently;
use fruently::fluent::Fluent;
use std::collections::HashMap;
use fruently::forwardable::JsonForwardable;

fn main() {
    let mut obj: HashMap<String, String> = HashMap::new();
    obj.insert("name".to_string(), "fruently".to_string());
    let fruently = Fluent::new("0.0.0.0:24224", "test");
    let _ = fruently.post(&obj);
}
<commit_msg>example main: Output error<commit_after>extern crate fruently;
use fruently::fluent::Fluent;
use std::collections::HashMap;
use fruently::forwardable::JsonForwardable;

fn main() {
    let mut obj: HashMap<String, String> = HashMap::new();
    obj.insert("name".to_string(), "fruently".to_string());
    let fruently = Fluent::new("0.0.0.0:24224", "test");
    match fruently.post(&obj) {
        Err(e) => println!("{:?}", e),
        Ok(_) => return,
    }
}
<|endoftext|>


<commit_before>//
// base64.rs - base64 implementation
//
// The Base64 Alphabet
//
//  Value Encoding  Value Encoding  Value Encoding  Value Encoding
//      0 A            17 R            34 i            51 z
//      1 B            18 S            35 j            52 0
//      2 C            19 T            36 k            53 1
//      3 D            20 U            37 l            54 2
//      4 E            21 V            38 m            55 3
//      5 F            22 W            39 n            56 4
//      6 G            23 X            40 o            57 5
//      7 H            24 Y            41 p            58 6
//      8 I            25 Z            42 q            59 7
//      9 J            26 a            43 r            60 8
//     10 K            27 b            44 s            61 9
//     11 L            28 c            45 t            62 +
//     12 M            29 d            46 u            63 /
//     13 N            30 e            47 v
//     14 O            31 f            48 w         (pad) =
//     15 P            32 g            49 x
//     16 Q            33 h            50 y
//
// The "URL and Filename safe" Base 64 Alphabet
//
// Value Encoding  Value Encoding  Value Encoding  Value Encoding
//     0 A            17 R            34 i            51 z
//     1 B            18 S            35 j            52 0
//     2 C            19 T            36 k            53 1
//     3 D            20 U            37 l            54 2
//     4 E            21 V            38 m            55 3
//     5 F            22 W            39 n            56 4
//     6 G            23 X            40 o            57 5
//     7 H            24 Y            41 p            58 6
//     8 I            25 Z            42 q            59 7
//     9 J            26 a            43 r            60 8
//    10 K            27 b            44 s            61 9
//    11 L            28 c            45 t            62 - (minus)
//    12 M            29 d            46 u            63 _ (underline)
//    13 N            30 e            47 v
//    14 O            31 f            48 w
//    15 P            32 g            49 x
//    16 Q            33 h            50 y         (pad) =
//

use std;

import std::map;
import std::map::hashmap;

export base64, mk;

const padd: u8 = 61u8;

iface base64 {
    fn encode(src: [u8]) -> [u8];
    fn decode(src: [u8]) -> [u8];
    fn decode2(src: [u8]) -> [u8];
    fn urlsafe_encode(src: [u8]) -> [u8];
    fn urlsafe_decode(src: [u8]) -> [u8];
    fn urlsafe_decode2(src: [u8]) -> [u8];
}

fn mk() -> base64 {
    type _base64 = {table: [u8]};

    impl of base64 for _base64 {
        fn encode(src: [u8]) -> [u8] {
            b64encode(self.table + [43u8, 47u8], src)
        }
        fn decode(src: [u8]) -> [u8] {
            b64decode(self.table + [43u8, 47u8], src)
        }
        fn urlsafe_encode(src: [u8]) -> [u8] {
            b64encode(self.table + [45u8, 95u8], src)
        }
        fn urlsafe_decode(src: [u8]) -> [u8] {
            b64decode(self.table + [45u8, 95u8], src)
        }
        fn decode2(src: [u8]) -> [u8] {
            b64decode2(self.table + [43u8, 47u8], src)
        }
        fn urlsafe_decode2(src: [u8]) -> [u8] {
            b64decode2(self.table + [45u8, 95u8], src)
        }
    }

    let table = vec::to_mut(vec::from_elem(62u, 0u8)), i = 0u8;
    u8::range(65u8, 91u8)  { |j| table[i] = j; i += 1u8; }
    u8::range(97u8, 123u8) { |j| table[i] = j; i += 1u8; }
    u8::range(48u8, 58u8)  { |j| table[i] = j; i += 1u8; }

    {table: vec::from_mut(table)} as base64
}

fn b64idx(x: u8, y: u8, z: u8) -> u8 {
    if 65u8 <= x && x <= 90u8 { x - 65u8 }
    else if 97u8 <= x && x <= 122u8 { x - 97u8 + 26u8 }
    else if 48u8 <= x && x <= 57u8  { x - 48u8 + 52u8 }
    else if x == y { 62u8 }
    else if x == z { 63u8 }
    else { fail "malformed base64 string"; }
}

fn b64encode(table: [u8], src: [u8]) -> [u8] {
    let srclen = vec::len(src);

    let targ: [mutable u8] = [mutable];
    let input = vec::to_mut(vec::from_elem(3u, 0u8));
    let output = vec::to_mut(vec::from_elem(4u, 0u8));
    let curr = 0u, src_curr = 0u;
    let targlen = if srclen % 3u == 0u {
        (srclen / 3u) * 4u
    } else {
        (srclen / 3u + 1u) * 4u
    };
    vec::reserve(targ, targlen);
    unsafe { vec::unsafe::set_len(targ, targlen); }

    while srclen > 2u {
        input[0] = src[src_curr];
        input[1] = src[src_curr + 1u];
        input[2] = src[src_curr + 2u];
        srclen -= 3u; src_curr += 3u;

        output[0] = input[0] >> 2u8;
        output[1] = ((input[0] &  3u8) << 4u8) | (input[1] >> 4u8);
        output[2] = ((input[1] & 15u8) << 2u8) | (input[2] >> 6u8);
        output[3] = input[2] & 63u8;

        targ[curr + 0u] = table[output[0]];
        targ[curr + 1u] = table[output[1]];
        targ[curr + 2u] = table[output[2]];
        targ[curr + 3u] = table[output[3]];
        curr += 4u;
    }

    if srclen != 0u {
        input[0] = 0u8; input[1] = 0u8; input[2] = 0u8;

        alt srclen {
          1u {input[0] = src[src_curr];}
          2u {input[0] = src[src_curr];
              input[1] = src[src_curr + 1u];}
          _  { }
        }

        output[0] = input[0] >> 2u8;
        output[1] = ((input[0] &  3u8) << 4u8) | (input[1] >> 4u8);
        output[2] = ((input[1] & 15u8) << 2u8) | (input[2] >> 6u8);

        targ[curr + 0u] = table[output[0]];
        targ[curr + 1u] = table[output[1]];
        targ[curr + 2u] = if srclen == 1u { padd } else { table[output[2]] };
        targ[curr + 3u] = padd;
    }

    vec::from_mut(targ)
}

// strict
fn b64decode(table: [u8], src: [u8]) -> [u8] {
    let srclen = vec::len(src);

    if srclen % 4u != 0u { fail "malformed base64 string"; }
    if srclen == 0u { ret []; }

    let targ: [mutable u8] = [mutable];
    let input  = vec::to_mut(vec::from_elem(4u, 0u8));
    let output = vec::to_mut(vec::from_elem(4u, 0u8));
    let curr = 0u, src_curr = 0u;
    let targlen =
        if src[srclen - 2u] == padd && src[srclen - 1u] == padd {
            srclen / 4u * 3u - 2u
        } else if src[srclen - 1u] == padd {
            srclen / 4u * 3u - 1u
        } else {
            srclen / 4u * 3u
        };
    vec::reserve(targ, targlen);
    unsafe { vec::unsafe::set_len(targ, targlen); }

    while srclen > 4u {
        input[0] = src[src_curr];
        input[1] = src[src_curr + 1u];
        input[2] = src[src_curr + 2u];
        input[3] = src[src_curr + 3u];
        srclen -= 4u; src_curr += 4u;

        output[0] = b64idx(input[0], table[62], table[63]);
        output[1] = b64idx(input[1], table[62], table[63]);
        output[2] = b64idx(input[2], table[62], table[63]);
        output[3] = b64idx(input[3], table[62], table[63]);

        targ[curr + 0u] = (output[0] << 2u8) | (output[1] >> 4u8);
        targ[curr + 1u] = ((output[1] & 15u8) << 4u8) | (output[2] >> 2u8);
        targ[curr + 2u] = ((output[2] &  3u8) << 6u8) | output[3];
        curr += 3u;
    }

    if srclen == 4u {
        input[0] = src[src_curr];
        input[1] = src[src_curr + 1u];
        input[2] = src[src_curr + 2u];
        input[3] = src[src_curr + 3u];

        output[0] = b64idx(input[0], table[62], table[63]);
        output[1] = b64idx(input[1], table[62], table[63]);

        targ[curr + 0u] = (output[0] << 2u8) | (output[1] >> 4u8);

        if input[2] == padd { ret vec::from_mut(targ); }

        output[2] = b64idx(input[2], table[62], table[63]);

        targ[curr + 1u] = ((output[1] & 15u8) << 4u8) | (output[2] >> 2u8);

        if input[3] == padd { ret vec::from_mut(targ); }

        output[3] = b64idx(input[3], table[62], table[63]);

        targ[curr + 2u] = ((output[2] & 3u8) << 6u8) | output[3];
    }

    vec::from_mut(targ)
}

// lenient
fn b64decode2(table: [u8], src: [u8]) -> [u8] {
    let srclen = vec::len(src);

    if srclen == 0u { ret []; }

    let targ: [mutable u8] = [mutable];
    let end = false, i = 0, in = 0u8;
    let output = vec::to_mut(vec::from_elem(4u, 0u8)), outlen = 4;
    let src_curr = 0u, curr = 0u;
    let targlen =
        if src[srclen - 2u] == padd && src[srclen - 1u] == padd {
            srclen / 4u * 3u - 2u
        } else if src[srclen - 1u] == padd {
            srclen / 4u * 3u - 1u
        } else {
            srclen / 4u * 3u
        };
    vec::reserve(targ, targlen);
    unsafe { vec::unsafe::set_len(targ, targlen); }

    while srclen > 0u && !end {
        i = 0;
        while i < 4 {
            if srclen == 0u {
                fail "malformed base64 string";
            }
            in = src[src_curr]; srclen -= 1u; src_curr += 1u;
            // ignore whitespace, tab, "\r", "\n"
            if in == 13u8 || in == 10u8 ||
               in == 32u8 || in == 9u8 {
                cont;
            }
            if in == padd && i >= 2 && srclen < 4u {
                if srclen > 0u && src[src_curr] != padd {
                    fail "malformed base64 string";
                }
                outlen = i; end = true;
                break;
            }
            output[i] = b64idx(in, table[62], table[63]);
            i += 1;
        }
        if outlen == 4 {
            targ[curr + 0u] = (output[0] << 2u8) | (output[1] >> 4u8);
            targ[curr + 1u] = ((output[1] & 15u8) << 4u8) | (output[2] >> 2u8);
            targ[curr + 2u] = ((output[2] &  3u8) << 6u8) | output[3];
            curr += 3u;
        } else if outlen == 3 {
            targ[curr + 0u] = (output[0] << 2u8) | (output[1] >> 4u8);
            targ[curr + 1u] = ((output[1] & 15u8) << 4u8) | (output[2] >> 2u8);
            curr += 2u;
        } else if outlen == 2 {
            targ[curr + 0u] = (output[0] << 2u8) | (output[1] >> 4u8);
            curr += 1u;
        }
    }

    let result: [mutable u8] = [mutable];
    vec::reserve(result, curr);
    vec::as_buf(result) { |dest|
        vec::as_buf(targ) { |src|
            if dest != ptr::null() && curr > 0u {
                unsafe { ptr::memcpy(dest, src, curr); }
            }
        }
    }
    unsafe { vec::unsafe::set_len(result, curr); }

    vec::from_mut(result)
}

// FIXME write
mod stream {
    type encoder = {
        base: io::writer,       // buffer, file, sockets, etc.
        buf: [mutable u8],      // buffer for fringe
        mutable buflen: uint,   // current length of ``buf''
        outbuf: [mutable u8],   // buffer for output
    };
    type decoder = {
        base: io::reader,       // buffer, file, sockets, etc.
        buf: [mutable u8],      // buffer for fringe
        mutable buflen: uint,   // current length of ``buf''
        outbuf: [mutable u8],   // buffer for output
    };
    // FIXME write
    impl of io::writer for encoder {
        fn write(v: [const u8]) {
            self.base.write(v);
        }
        fn seek(offset: int, whence: io::seek_style) {
            self.base.seek(offset, whence);
        }
        fn tell() -> uint {
            self.base.tell()
        }
        fn flush() -> int {
            self.base.flush()
        }
    }
    // FIXME write
    impl of io::reader for decoder {
        fn read_bytes(len: uint) -> [u8] {
            self.base.read_bytes(len)
        }
        fn read_byte() -> int {
            self.base.read_byte()
        }
        fn unread_byte(byte: int) {
            self.base.unread_byte(byte);
        }
        fn eof() -> bool {
            self.base.eof()
        }
        fn seek(offset: int, whence: io::seek_style) {
            self.base.seek(offset, whence)
        }
        fn tell() -> uint {
            self.base.tell()
        }
    }
    // FIXME write
    fn mk_encoder(_eo: io::writer) {
    }
    // FIXME write
    fn mk_decoder(_ei: io::reader) {
    }
}

#[cfg(test)]
mod tests {
    import core::str::{from_bytes, bytes};
    enum mode {
        t_decode,
        t_encode,
        t_urlsafe_encode,
        t_urlsafe_decode,
        t_decode2,
        t_urlsafe_decode2,
    }
    fn setup(t: mode) -> map::hashmap<str, str> {
        let m = map::new_str_hash::<str>();
        m.insert("", "");
        alt t {
          t_decode2 | t_urlsafe_decode2 {
            m.insert("cGxl    YXN1cmUu", "pleasure.");
            m.insert("bGVhc 3VyZS4=",  "leasure.");
            m.insert("Z W F z d X J l L g==",   "easure.");
            m.insert("YXN1c\r\nmUu",        "asure.");
            m.insert("c3Vy\tZS4=",         "sure.");
          }
          t_decode | t_urlsafe_decode {
            m.insert("cGxlYXN1cmUu", "pleasure.");
            m.insert("bGVhc3VyZS4=",  "leasure.");
            m.insert("ZWFzdXJlLg==",   "easure.");
            m.insert("YXN1cmUu",        "asure.");
            m.insert("c3VyZS4=",         "sure.");
          }
           t_encode | t_urlsafe_encode {
            m.insert("pleasure.", "cGxlYXN1cmUu");
            m.insert("leasure.",  "bGVhc3VyZS4=");
            m.insert("easure.",   "ZWFzdXJlLg==");
            m.insert("asure.",        "YXN1cmUu");
            m.insert("sure.",         "c3VyZS4=");
          }
        }
        m
    }
    fn do_test(t: mode) {
        let b64 = mk();
        let m = setup(t);
        m.keys { |k|
            let expected = m.get(k);
            let actual = alt t {
              t_decode { from_bytes(b64.decode(bytes(k))) }
              t_encode { from_bytes(b64.encode(bytes(k))) }
              t_urlsafe_decode { from_bytes(b64.urlsafe_decode(bytes(k))) }
              t_urlsafe_encode { from_bytes(b64.urlsafe_encode(bytes(k))) }
              t_decode2 { from_bytes(b64.decode2(bytes(k))) }
              t_urlsafe_decode2 { from_bytes(b64.urlsafe_decode2(bytes(k))) }
            };
            #debug("  expected: %s", expected);
            #debug("  actual:   %s", actual);
            assert expected == actual;
        }
    }
    #[test]
    fn decode() { do_test(t_decode); }
    #[test]
    fn encode() { do_test(t_encode); }
    #[test]
    fn urlsafe_decode() { do_test(t_urlsafe_decode); }
    #[test]
    fn urlsafe_encode() { do_test(t_urlsafe_encode); }
    #[test]
    fn decode2() { do_test(t_decode2); }
    #[test]
    fn urlsafe_decode2() { do_test(t_urlsafe_decode2); }
    #[test]
    fn tmp_stream_encoder() {
        // let reader = io::string_reader("foo");
        // let expected = "Zm9y";
        // let result = base64::with_str_encoder { |encoder|
        //     reader.iter { |data|
        //         encoder.write(data);
        //     }
        // };
        // assert expected == result;
        assert true;
    }
    #[test]
    fn tmp_stream_decoder() {
        // let decoder = base64::string_decoder("Zm9y");
        // let expected = "foo";
        // let result = io::with_str_writer { |buf|
        //     decoder.iter { |data|
        //         buf.write(data);
        //     }
        // };
        // assert expected == result;
        assert true;
    }
}
<commit_msg>byebye old one<commit_after><|endoftext|>


<commit_before>use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Error;
use memory::Memory;

struct Cpu6502 {
  registers: Registers,
  memory: Memory
}

struct Registers {
  pc: u16, // Program Counter
  sp: u8, // Stack Pointer
  acc: u8, // Accumulator
  irx: u8, // Index Register X
  iry: u8, // Index Register Y
  stat: u8 // Processor Status Flags
}

impl Registers {
  fn new() -> Registers {
    Registers {
      pc: 0,
      sp: 0,
      acc: 0,
      irx: 0,
      iry: 0,
      stat: 0
    }
  }
}

impl Cpu6502 {
  fn new() -> Cpu6502 {
    Cpu6502 {
      registers: Registers::new(),
      memory: Memory::new()
    }
  }
}

impl Display for Cpu6502 {
  fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
    write!(formatter, "{}|{}|{}|{}|{}|{}",
        self.registers.pc, self.registers.sp, self.registers.acc,
        self.registers.irx, self.registers.iry, self.registers.stat)
  }
}
<commit_msg>Consolidate using statements<commit_after>use std::fmt::{Display, Formatter, Error};
use memory::Memory;

struct Cpu6502 {
  registers: Registers,
  memory: Memory
}

struct Registers {
  pc: u16, // Program Counter
  sp: u8, // Stack Pointer
  acc: u8, // Accumulator
  irx: u8, // Index Register X
  iry: u8, // Index Register Y
  stat: u8 // Processor Status Flags
}

impl Registers {
  fn new() -> Registers {
    Registers {
      pc: 0,
      sp: 0,
      acc: 0,
      irx: 0,
      iry: 0,
      stat: 0
    }
  }
}

impl Cpu6502 {
  fn new() -> Cpu6502 {
    Cpu6502 {
      registers: Registers::new(),
      memory: Memory::new()
    }
  }
}

impl Display for Cpu6502 {
  fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
    write!(formatter, "{}|{}|{}|{}|{}|{}",
        self.registers.pc, self.registers.sp, self.registers.acc,
        self.registers.irx, self.registers.iry, self.registers.stat)
  }
}
<|endoftext|>


<commit_before>#[cfg(feature = "ssl")]
use std::io::{Error, ErrorKind};
use std::io::{Read, Result, Write};
use std::net::{SocketAddr, TcpStream};

#[cfg(feature = "ssl")]
use openssl::ssl::{Ssl, SslContext, SslFiletype, SslMethod, SslOptions, SslStream, SslVerifyMode};

/// Encapsulates the functionality for how to connect to the server.
#[derive(Clone)]
pub enum StreamConnector {
    /// Connect to the server through a regular TCP stream.
    Tcp,
    #[cfg(feature = "ssl")]
    /// Connect to the server through a TCP stream encrypted with SSL.
    ///
    /// Note that it's invalid to have one of certificate_file and key_file set but not the other.
    Ssl {
        ca_file: Option<String>,
        certificate_file: Option<String>,
        key_file: Option<String>,
        verify_peer: bool,
    },
}

impl Default for StreamConnector {
    fn default() -> Self {
        StreamConnector::Tcp
    }
}

impl StreamConnector {
    #[cfg(feature = "ssl")]
    /// Creates a StreamConnector that will connect with SSL encryption.
    ///
    /// The SSL connection will use the cipher with the longest key length available to both the
    /// server and client, with the following caveats:
    ///   * SSLv2 and SSlv3 are disabled
    ///   * Export-strength ciphers are disabled
    ///   * Ciphers not offering encryption are disabled
    ///   * Ciphers not offering authentication are disabled
    ///   * Ciphers with key lengths of 128 or fewer bits are disabled.
    ///
    /// Note that TLS compression is disabled for SSL connections.
    ///
    /// # Arguments
    ///
    /// `ca_file` - Path to the file containing trusted CA certificates.
    /// `certificate_file` - Path to the file containing the client certificate.
    /// `key_file` - Path to the file containing the client private key.
    /// `verify_peer` - Whether or not to verify that the server's certificate is trusted.
    pub fn with_ssl(
        ca_file: Option<&str>,
        certificate_file: &str,
        key_file: &str,
        verify_peer: bool,
    ) -> Self {
        StreamConnector::Ssl {
            ca_file: ca_file.map(String::from),
            certificate_file: Some(String::from(certificate_file)),
            key_file: Some(String::from(key_file)),
            verify_peer: verify_peer,
        }
    }

    #[cfg(feature = "ssl")]
    /// Creates an unauthenticated StreamConnector that will connect with SSL encryption.
    ///
    /// The SSL connection will use the cipher with the longest key length available to both the
    /// server and client, with the following caveats:
    ///   * SSLv2 and SSlv3 are disabled
    ///   * Export-strength ciphers are disabled
    ///   * Ciphers not offering encryption are disabled
    ///   * Ciphers not offering authentication are disabled
    ///   * Ciphers with key lengths of 128 or fewer bits are disabled.
    ///
    /// Note that TLS compression is disabled for SSL connections.
    ///
    /// # Arguments
    ///
    /// `ca_file` - Path to the file containing trusted CA certificates.
    /// `verify_peer` - Whether or not to verify that the server's certificate is trusted.
    pub fn with_unauthenticated_ssl(ca_file: Option<&str>, verify_peer: bool) -> Self {
        StreamConnector::Ssl {
            ca_file: ca_file.map(String::from),
            certificate_file: None,
            key_file: None,
            verify_peer: verify_peer,
        }
    }

    pub fn connect(&self, hostname: &str, port: u16) -> Result<Stream> {
        match *self {
            StreamConnector::Tcp => TcpStream::connect((hostname, port)).map(Stream::Tcp),
            #[cfg(feature = "ssl")]
            StreamConnector::Ssl {
                ref ca_file,
                ref certificate_file,
                ref key_file,
                verify_peer,
            } => {
                let inner_stream = TcpStream::connect((hostname, port))?;

                let mut ssl_context = SslContext::builder(SslMethod::tls())?;
                ssl_context.set_cipher_list("ALL:!EXPORT:!eNULL:!aNULL:HIGH:@STRENGTH")?;
                ssl_context.set_options(SslOptions::NO_SSLV2);
                ssl_context.set_options(SslOptions::NO_SSLV3);
                ssl_context.set_options(SslOptions::NO_COMPRESSION);

                if let Some(ca_file) = ca_file {
                    ssl_context.set_ca_file(ca_file)?;
                }

                if let &Some(ref file) = certificate_file {
                    ssl_context.set_certificate_file(file, SslFiletype::PEM)?;
                }
                if let &Some(ref file) = key_file {
                    ssl_context.set_private_key_file(file, SslFiletype::PEM)?;
                }

                let verify = if verify_peer {
                    SslVerifyMode::PEER
                } else {
                    SslVerifyMode::NONE
                };
                ssl_context.set_verify(verify);

                let mut ssl = Ssl::new(&ssl_context.build())?;
                ssl.set_hostname(hostname)?;

                match ssl.connect(inner_stream) {
                    Ok(s) => Ok(Stream::Ssl(s)),
                    Err(e) => Err(Error::new(ErrorKind::Other, e)),
                }
            }
        }
    }
}

pub enum Stream {
    Tcp(TcpStream),
    #[cfg(feature = "ssl")]
    Ssl(SslStream<TcpStream>),
}

impl Read for Stream {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        match *self {
            Stream::Tcp(ref mut s) => s.read(buf),
            #[cfg(feature = "ssl")]
            Stream::Ssl(ref mut s) => s.read(buf),
        }
    }
}

impl Write for Stream {
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        match *self {
            Stream::Tcp(ref mut s) => s.write(buf),
            #[cfg(feature = "ssl")]
            Stream::Ssl(ref mut s) => s.write(buf),
        }
    }

    fn flush(&mut self) -> Result<()> {
        match *self {
            Stream::Tcp(ref mut s) => s.flush(),
            #[cfg(feature = "ssl")]
            Stream::Ssl(ref mut s) => s.flush(),
        }
    }
}

impl Stream {
    pub fn peer_addr(&self) -> Result<SocketAddr> {
        match *self {
            Stream::Tcp(ref stream) => stream.peer_addr(),
            #[cfg(feature = "ssl")]
            Stream::Ssl(ref stream) => stream.get_ref().peer_addr(),
        }
    }
}
<commit_msg>Set TCP_NODELAY for the socket (#305)<commit_after>use std::io::{BufReader, Read, Result, Write};
#[cfg(feature = "ssl")]
use std::io::{Error, ErrorKind};
use std::net::{SocketAddr, TcpStream};

#[cfg(feature = "ssl")]
use openssl::ssl::{Ssl, SslContext, SslFiletype, SslMethod, SslOptions, SslStream, SslVerifyMode};

/// Encapsulates the functionality for how to connect to the server.
#[derive(Clone)]
pub enum StreamConnector {
    /// Connect to the server through a regular TCP stream.
    Tcp,
    #[cfg(feature = "ssl")]
    /// Connect to the server through a TCP stream encrypted with SSL.
    ///
    /// Note that it's invalid to have one of certificate_file and key_file set but not the other.
    Ssl {
        ca_file: Option<String>,
        certificate_file: Option<String>,
        key_file: Option<String>,
        verify_peer: bool,
    },
}

impl Default for StreamConnector {
    fn default() -> Self {
        StreamConnector::Tcp
    }
}

impl StreamConnector {
    #[cfg(feature = "ssl")]
    /// Creates a StreamConnector that will connect with SSL encryption.
    ///
    /// The SSL connection will use the cipher with the longest key length available to both the
    /// server and client, with the following caveats:
    ///   * SSLv2 and SSlv3 are disabled
    ///   * Export-strength ciphers are disabled
    ///   * Ciphers not offering encryption are disabled
    ///   * Ciphers not offering authentication are disabled
    ///   * Ciphers with key lengths of 128 or fewer bits are disabled.
    ///
    /// Note that TLS compression is disabled for SSL connections.
    ///
    /// # Arguments
    ///
    /// `ca_file` - Path to the file containing trusted CA certificates.
    /// `certificate_file` - Path to the file containing the client certificate.
    /// `key_file` - Path to the file containing the client private key.
    /// `verify_peer` - Whether or not to verify that the server's certificate is trusted.
    pub fn with_ssl(
        ca_file: Option<&str>,
        certificate_file: &str,
        key_file: &str,
        verify_peer: bool,
    ) -> Self {
        StreamConnector::Ssl {
            ca_file: ca_file.map(String::from),
            certificate_file: Some(String::from(certificate_file)),
            key_file: Some(String::from(key_file)),
            verify_peer: verify_peer,
        }
    }

    #[cfg(feature = "ssl")]
    /// Creates an unauthenticated StreamConnector that will connect with SSL encryption.
    ///
    /// The SSL connection will use the cipher with the longest key length available to both the
    /// server and client, with the following caveats:
    ///   * SSLv2 and SSlv3 are disabled
    ///   * Export-strength ciphers are disabled
    ///   * Ciphers not offering encryption are disabled
    ///   * Ciphers not offering authentication are disabled
    ///   * Ciphers with key lengths of 128 or fewer bits are disabled.
    ///
    /// Note that TLS compression is disabled for SSL connections.
    ///
    /// # Arguments
    ///
    /// `ca_file` - Path to the file containing trusted CA certificates.
    /// `verify_peer` - Whether or not to verify that the server's certificate is trusted.
    pub fn with_unauthenticated_ssl(ca_file: Option<&str>, verify_peer: bool) -> Self {
        StreamConnector::Ssl {
            ca_file: ca_file.map(String::from),
            certificate_file: None,
            key_file: None,
            verify_peer: verify_peer,
        }
    }

    pub fn connect(&self, hostname: &str, port: u16) -> Result<Stream> {
        match *self {
            StreamConnector::Tcp => {
                let stream = TcpStream::connect((hostname, port))?;
                stream.set_nodelay(true)?;
                Ok(Stream::Tcp {
                    read_half: BufReader::new(stream.try_clone()?),
                    write_half: stream,
                })
            }
            #[cfg(feature = "ssl")]
            StreamConnector::Ssl {
                ref ca_file,
                ref certificate_file,
                ref key_file,
                verify_peer,
            } => {
                let inner_stream = TcpStream::connect((hostname, port))?;
                inner_stream.set_nodelay(true)?;

                let mut ssl_context = SslContext::builder(SslMethod::tls())?;
                ssl_context.set_cipher_list("ALL:!EXPORT:!eNULL:!aNULL:HIGH:@STRENGTH")?;
                ssl_context.set_options(SslOptions::NO_SSLV2);
                ssl_context.set_options(SslOptions::NO_SSLV3);
                ssl_context.set_options(SslOptions::NO_COMPRESSION);

                if let Some(ca_file) = ca_file {
                    ssl_context.set_ca_file(ca_file)?;
                }

                if let &Some(ref file) = certificate_file {
                    ssl_context.set_certificate_file(file, SslFiletype::PEM)?;
                }
                if let &Some(ref file) = key_file {
                    ssl_context.set_private_key_file(file, SslFiletype::PEM)?;
                }

                let verify = if verify_peer {
                    SslVerifyMode::PEER
                } else {
                    SslVerifyMode::NONE
                };
                ssl_context.set_verify(verify);

                let mut ssl = Ssl::new(&ssl_context.build())?;
                ssl.set_hostname(hostname)?;

                match ssl.connect(inner_stream) {
                    Ok(s) => Ok(Stream::Ssl(s)),
                    Err(e) => Err(Error::new(ErrorKind::Other, e)),
                }
            }
        }
    }
}

pub enum Stream {
    Tcp {
        read_half: BufReader<TcpStream>,
        write_half: TcpStream,
    },
    #[cfg(feature = "ssl")]
    Ssl(SslStream<TcpStream>),
}

impl Read for Stream {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        match *self {
            Stream::Tcp {
                ref mut read_half, ..
            } => read_half.read(buf),
            #[cfg(feature = "ssl")]
            Stream::Ssl(ref mut s) => s.read(buf),
        }
    }
}

impl Write for Stream {
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        match *self {
            Stream::Tcp {
                ref mut write_half, ..
            } => write_half.write(buf),
            #[cfg(feature = "ssl")]
            Stream::Ssl(ref mut s) => s.write(buf),
        }
    }

    fn flush(&mut self) -> Result<()> {
        match *self {
            Stream::Tcp {
                ref mut write_half, ..
            } => write_half.flush(),
            #[cfg(feature = "ssl")]
            Stream::Ssl(ref mut s) => s.flush(),
        }
    }
}

impl Stream {
    pub fn peer_addr(&self) -> Result<SocketAddr> {
        match *self {
            Stream::Tcp { ref write_half, .. } => write_half.peer_addr(),
            #[cfg(feature = "ssl")]
            Stream::Ssl(ref stream) => stream.get_ref().peer_addr(),
        }
    }
}
<|endoftext|>


<commit_before>pub use self::imp::*;

#[cfg(not(cross_platform_docs))]
mod imp {
    pub use core::clone::Clone;
    pub use core::marker::Copy;
    pub use core::mem;
    pub use core::option::Option;
}

#[cfg(cross_platform_docs)]
mod imp {
    pub enum Option<T> {
        Some(T),
        None,
    }
    impl<T: Copy> Copy for Option<T> {}
    impl<T: Clone> Clone for Option<T> {
        fn clone(&self) -> Option<T> {
            loop {}
        }
    }

    impl<T> Copy for *mut T {}
    impl<T> Clone for *mut T {
        fn clone(&self) -> *mut T {
            loop {}
        }
    }

    impl<T> Copy for *const T {}
    impl<T> Clone for *const T {
        fn clone(&self) -> *const T {
            loop {}
        }
    }

    pub trait Clone {
        fn clone(&self) -> Self;
    }

    #[lang = "copy"]
    pub trait Copy {}

    #[lang = "freeze"]
    pub trait Freeze {}

    #[lang = "sync"]
    pub trait Sync {}
    impl<T> Sync for T {}

    #[lang = "sized"]
    pub trait Sized {}

    macro_rules! each_int {
        ($mac:ident) => {
            $mac!(u8);
            $mac!(u16);
            $mac!(u32);
            $mac!(u64);
            $mac!(usize);
            each_signed_int!($mac);
        };
    }

    macro_rules! each_signed_int {
        ($mac:ident) => {
            $mac!(i8);
            $mac!(i16);
            $mac!(i32);
            $mac!(i64);
            $mac!(isize);
        };
    }

    #[lang = "div"]
    pub trait Div<RHS = Self> {
        type Output;
        fn div(self, rhs: RHS) -> Self::Output;
    }

    #[lang = "shl"]
    pub trait Shl<RHS = Self> {
        type Output;
        fn shl(self, rhs: RHS) -> Self::Output;
    }

    #[lang = "mul"]
    pub trait Mul<RHS = Self> {
        type Output;
        fn mul(self, rhs: RHS) -> Self::Output;
    }

    #[lang = "sub"]
    pub trait Sub<RHS = Self> {
        type Output;
        fn sub(self, rhs: RHS) -> Self::Output;
    }

    #[lang = "bitand"]
    pub trait BitAnd<RHS = Self> {
        type Output;
        fn bitand(self, rhs: RHS) -> Self::Output;
    }

    #[lang = "bitand_assign"]
    pub trait BitAndAssign<RHS = Self> {
        fn bitand_assign(&mut self, rhs: RHS);
    }

    #[lang = "bitor"]
    pub trait BitOr<RHS = Self> {
        type Output;
        fn bitor(self, rhs: RHS) -> Self::Output;
    }

    #[lang = "bitor_assign"]
    pub trait BitOrAssign<RHS = Self> {
        fn bitor_assign(&mut self, rhs: RHS);
    }

    #[lang = "bitxor"]
    pub trait BitXor<RHS = Self> {
        type Output;
        fn bitxor(self, rhs: RHS) -> Self::Output;
    }

    #[lang = "bitxor_assign"]
    pub trait BitXorAssign<RHS = Self> {
        fn bitxor_assign(&mut self, rhs: RHS);
    }

    #[lang = "neg"]
    pub trait Neg {
        type Output;
        fn neg(self) -> Self::Output;
    }

    #[lang = "not"]
    pub trait Not {
        type Output;
        fn not(self) -> Self::Output;
    }

    #[lang = "add"]
    pub trait Add<RHS = Self> {
        type Output;
        fn add(self, r: RHS) -> Self::Output;
    }

    macro_rules! impl_traits {
        ($($i:ident)*) => ($(
            impl Div<$i> for $i {
                type Output = $i;
                fn div(self, rhs: $i) -> $i { self / rhs }
            }
            impl Shl<$i> for $i {
                type Output = $i;
                fn shl(self, rhs: $i) -> $i { self << rhs }
            }
            impl Mul for $i {
                type Output = $i;
                fn mul(self, rhs: $i) -> $i { self * rhs }
            }

            impl Sub for $i {
                type Output = $i;
                fn sub(self, rhs: $i) -> $i { self - rhs }
            }
            impl BitAnd for $i {
                type Output = $i;
                fn bitand(self, rhs: $i) -> $i { self & rhs }
            }
            impl BitAndAssign for $i {
                fn bitand_assign(&mut self, rhs: $i) { *self &= rhs; }
            }
            impl BitOr for $i {
                type Output = $i;
                fn bitor(self, rhs: $i) -> $i { self | rhs }
            }
            impl BitOrAssign for $i {
                fn bitor_assign(&mut self, rhs: $i) { *self |= rhs; }
            }
            impl BitXor for $i {
                type Output = $i;
                fn bitxor(self, rhs: $i) -> $i { self ^ rhs }
            }
            impl BitXorAssign for $i {
                fn bitxor_assign(&mut self, rhs: $i) { *self ^= rhs; }
            }
            impl Neg for $i {
                type Output = $i;
                fn neg(self) -> $i { -self }
            }
            impl Not for $i {
                type Output = $i;
                fn not(self) -> $i { !self }
            }
            impl Add<$i> for $i {
                type Output = $i;
                fn add(self, other: $i) -> $i { self + other }
            }
            impl Copy for $i {}
            impl Clone for $i {
                fn clone(&self) -> $i { loop {} }
            }
        )*)
    }
    each_int!(impl_traits);

    pub mod mem {
        pub fn size_of_val<T>(_: &T) -> usize {
            4
        }
        pub const fn size_of<T>() -> usize {
            4
        }
    }
}
<commit_msg>Fix docs on nightly<commit_after>pub use self::imp::*;

#[cfg(not(cross_platform_docs))]
mod imp {
    pub use core::clone::Clone;
    pub use core::marker::Copy;
    pub use core::mem;
    pub use core::option::Option;
}

#[cfg(cross_platform_docs)]
mod imp {
    pub enum Option<T> {
        Some(T),
        None,
    }
    impl<T: Copy> Copy for Option<T> {}
    impl<T: Clone> Clone for Option<T> {
        fn clone(&self) -> Option<T> {
            loop {}
        }
    }

    impl<T> Copy for *mut T {}
    impl<T> Clone for *mut T {
        fn clone(&self) -> *mut T {
            loop {}
        }
    }

    impl<T> Copy for *const T {}
    impl<T> Clone for *const T {
        fn clone(&self) -> *const T {
            loop {}
        }
    }

    pub trait Clone {
        fn clone(&self) -> Self;
    }

    #[lang = "copy"]
    pub trait Copy {}

    #[lang = "freeze"]
    pub trait Freeze {}

    #[lang = "sync"]
    pub trait Sync {}
    impl<T> Sync for T {}

    #[lang = "sized"]
    pub trait Sized {}

    #[lang = "receiver"]
    pub trait Receiver {}
    impl<T: ?Sized> Receiver for &T {}
    impl<T: ?Sized> Receiver for &mut T {}

    macro_rules! each_int {
        ($mac:ident) => {
            $mac!(u8);
            $mac!(u16);
            $mac!(u32);
            $mac!(u64);
            $mac!(usize);
            each_signed_int!($mac);
        };
    }

    macro_rules! each_signed_int {
        ($mac:ident) => {
            $mac!(i8);
            $mac!(i16);
            $mac!(i32);
            $mac!(i64);
            $mac!(isize);
        };
    }

    #[lang = "div"]
    pub trait Div<RHS = Self> {
        type Output;
        fn div(self, rhs: RHS) -> Self::Output;
    }

    #[lang = "shl"]
    pub trait Shl<RHS = Self> {
        type Output;
        fn shl(self, rhs: RHS) -> Self::Output;
    }

    #[lang = "mul"]
    pub trait Mul<RHS = Self> {
        type Output;
        fn mul(self, rhs: RHS) -> Self::Output;
    }

    #[lang = "sub"]
    pub trait Sub<RHS = Self> {
        type Output;
        fn sub(self, rhs: RHS) -> Self::Output;
    }

    #[lang = "bitand"]
    pub trait BitAnd<RHS = Self> {
        type Output;
        fn bitand(self, rhs: RHS) -> Self::Output;
    }

    #[lang = "bitand_assign"]
    pub trait BitAndAssign<RHS = Self> {
        fn bitand_assign(&mut self, rhs: RHS);
    }

    #[lang = "bitor"]
    pub trait BitOr<RHS = Self> {
        type Output;
        fn bitor(self, rhs: RHS) -> Self::Output;
    }

    #[lang = "bitor_assign"]
    pub trait BitOrAssign<RHS = Self> {
        fn bitor_assign(&mut self, rhs: RHS);
    }

    #[lang = "bitxor"]
    pub trait BitXor<RHS = Self> {
        type Output;
        fn bitxor(self, rhs: RHS) -> Self::Output;
    }

    #[lang = "bitxor_assign"]
    pub trait BitXorAssign<RHS = Self> {
        fn bitxor_assign(&mut self, rhs: RHS);
    }

    #[lang = "neg"]
    pub trait Neg {
        type Output;
        fn neg(self) -> Self::Output;
    }

    #[lang = "not"]
    pub trait Not {
        type Output;
        fn not(self) -> Self::Output;
    }

    #[lang = "add"]
    pub trait Add<RHS = Self> {
        type Output;
        fn add(self, r: RHS) -> Self::Output;
    }

    macro_rules! impl_traits {
        ($($i:ident)*) => ($(
            impl Div<$i> for $i {
                type Output = $i;
                fn div(self, rhs: $i) -> $i { self / rhs }
            }
            impl Shl<$i> for $i {
                type Output = $i;
                fn shl(self, rhs: $i) -> $i { self << rhs }
            }
            impl Mul for $i {
                type Output = $i;
                fn mul(self, rhs: $i) -> $i { self * rhs }
            }

            impl Sub for $i {
                type Output = $i;
                fn sub(self, rhs: $i) -> $i { self - rhs }
            }
            impl BitAnd for $i {
                type Output = $i;
                fn bitand(self, rhs: $i) -> $i { self & rhs }
            }
            impl BitAndAssign for $i {
                fn bitand_assign(&mut self, rhs: $i) { *self &= rhs; }
            }
            impl BitOr for $i {
                type Output = $i;
                fn bitor(self, rhs: $i) -> $i { self | rhs }
            }
            impl BitOrAssign for $i {
                fn bitor_assign(&mut self, rhs: $i) { *self |= rhs; }
            }
            impl BitXor for $i {
                type Output = $i;
                fn bitxor(self, rhs: $i) -> $i { self ^ rhs }
            }
            impl BitXorAssign for $i {
                fn bitxor_assign(&mut self, rhs: $i) { *self ^= rhs; }
            }
            impl Neg for $i {
                type Output = $i;
                fn neg(self) -> $i { -self }
            }
            impl Not for $i {
                type Output = $i;
                fn not(self) -> $i { !self }
            }
            impl Add<$i> for $i {
                type Output = $i;
                fn add(self, other: $i) -> $i { self + other }
            }
            impl Copy for $i {}
            impl Clone for $i {
                fn clone(&self) -> $i { loop {} }
            }
        )*)
    }
    each_int!(impl_traits);

    pub mod mem {
        pub fn size_of_val<T>(_: &T) -> usize {
            4
        }
        pub const fn size_of<T>() -> usize {
            4
        }
    }
}
<|endoftext|>


<commit_before>use std::fmt::Debug;
use std::mem;
use std::sync::mpsc;
use std::sync::RwLock;

use rayon::prelude::*;
use rayon;
use anymap;

#[derive(Clone, Default, Debug)]
pub struct Component {
    data: i32,
}

// #[derive(Clone, Default)]
// pub struct VecResource<T> {
//     data: Vec<T>,
// }

#[derive(Clone, Default, Debug)]
pub struct VecResource<T>
    where T: Debug
{
    data: Vec<T>,
}

impl<T> VecResource<T>
    where T: Debug
{
    pub fn new() -> Self {
        VecResource { data: Vec::new() }
    }
}

#[derive(Clone, Debug)]
pub struct Entity(u32);

pub type InputChannel<T> = Vec<T>;
pub type OutputChannel<T> = mpsc::Sender<T>;

pub struct EventSender<E> {
    channels: Vec<RwLock<Vec<E>>>
}

// We never clone the channel senders, so I'm not sure if this is
// really better than just having a Vec<RwLock<E>>, but...
impl<E> EventSender<E> where E: Send + Sync {
    fn new() -> Self {
        EventSender {
            channels: Vec::new(),
        }
    }

    pub fn send_to_entity(&self, entity: Entity, event: E) {
        let channel = self.channels.get(entity.0 as usize).expect("Sent message to non-existent entity!");
        let channel_write = &mut channel.write().expect("Attempted to write on poisoned RwLock, aiee!");
        channel_write.push(event);
    }

    pub fn clear(&mut self) {
        // Might as well parallelize?
        // Overhead might not make it worth it.
        // Try it later, see if it matters.

        self.channels.par_iter()
            .for_each(|q| {
                // Not sure if this is actually an optimization but it might be?
                // Depends on how expensive getting a write lock is.
                // ...Probably not more expensive than getting a read lock, tbh.
                let to_clear = {
                    let q_read = &mut q.try_read().unwrap();
                    q_read.len() > 0
                };
                if to_clear {
                    let q_write = &mut q.try_write().expect("Tried to clear event queues while in use; should never happen!");
                    q_write.clear();
                }
            });
    }
}

// I feel a little ghetto making one global event type for everything,
// but we'll roll with it for now.
pub struct World<E> where E: Send {
    entities: Vec<Entity>,
    current_components: anymap::AnyMap,
    next_components: anymap::AnyMap,
    current_events: EventSender<E>,
    next_events: EventSender<E>,
}

impl<E> World<E> where E: Send + Sync {
    pub fn new() -> Self {
        World {
            entities: Vec::new(),
            current_components: anymap::AnyMap::new(),
            next_components: anymap::AnyMap::new(),
            current_events: EventSender::new(),
            next_events: EventSender::new(),
        }
    }

    fn register<T>(&mut self)
        where T: Default + 'static
    {
        self.current_components.insert(T::default());
        self.next_components.insert(T::default());
    }

    fn run1<F, C>(&mut self, f: F)
        where F: Fn(&C, &[E], &EventSender<E>) -> C + Sync,
              C: Debug + Send + Sync + 'static
    {
        if let Some(resource) = self.current_components.get::<VecResource<C>>() {
            if let Some(next_components) = self.next_components.get_mut::<VecResource<C>>() {
                let d: &[C] = &resource.data;
                let v = &mut next_components.data;
                let next_events = &self.next_events;
                d.par_iter()
                    .zip(&self.current_events.channels)
                    .map(|(c, e)| {
                        let event_queue = e.read().expect("Aiee event queue is poisoned in World::run()");
                        f(c, &event_queue[..], next_events)
                    })
                    .collect_into(v);
            } else {
                panic!("current_components exists but next_components does not, this should never happen!")
            }
        } else {
            panic!("Tried to run a system on an unknown component type");
        }
    }

    fn run2<F, C1, C2>(&mut self, f: F)
        where F: Fn(&C1, &C2, &[E], &EventSender<E>) -> (C1, C2) + Sync,
              C1: Debug + Send + Sync + 'static,
              C2: Debug + Send + Sync + 'static
    {
        let current1 = self.current_components.get::<VecResource<C1>>().expect("Tried to run a system on an unknown component type");
        let current2 = self.current_components.get::<VecResource<C2>>().expect("Tried to run a system on an unknown component type");
        let c1: &[C1] = &current1.data;
        let c2: &[C2] = &current2.data;

        let next_events = &self.next_events;
        // BUGGO: Aieee, my perfect non-allocating system is now poisoned!
        let mut next_hax: Vec<(C1, C2)> = Vec::with_capacity(c1.len());
        c1.par_iter()
            .zip(c2)
            .zip(&self.current_events.channels)
            .map(|((comp1, comp2), e)| {
                let event_queue = e.read().expect("Aiee event queue is poisoned in World::run(); did a system crash?");
                f(comp1, comp2, &event_queue[..], next_events)
            })
            .collect_into(&mut next_hax);
        //.enumerate()
        // This doesn't seem to work 'cause it gets pesky about the closure altering self,
        // for some reason.  Hmm.
        //.for_each(|(i, (comp1, comp2))| {
            //    next1.data[i] = comp1;
            //});
        //.collect_into(v);
        let (r1, r2): (Vec<C1>, Vec<C2>) = next_hax.into_iter().unzip();
        {
            let next1 = self.next_components.get_mut::<VecResource<C1>>().expect("current_components exists but next_components does not, this should never happen!");
            let n1 = &mut next1.data;
            *n1 = r1;
        }
        {
            let next2 = self.next_components.get_mut::<VecResource<C2>>().expect("current_components exists but next_components does not, this should never happen!");
            let n2 = &mut next2.data;
            *n2 = r2;
        }
    }

    // This function finalizes the end of the frame.
    // Delivers events, flips the current and next components, etc.
    fn finish(&mut self) {
        // Switch components
        {
            let m1 = &mut self.current_components;
            let m2 = &mut self.next_components;
            mem::swap(m1, m2);
        }

        // empty out old events, deliver new ones.
        // Making the iterator work easily takes a little
        // bit of explicit type-mongling
        {
            let e1 = &mut self.current_events;
            let e2 = &mut self.next_events;
            mem::swap(e1, e2);
        }
        self.next_events.clear();
    }

    fn next_entity(&self) -> Entity {
        use std::u32;
        assert!(self.entities.len() < u32::MAX as usize);
        Entity(self.entities.len() as u32)
    }

    fn create_entity<C1, C2>(&mut self, component1: C1, component2: C2) -> Entity
        where C1: Debug + Send + Sync + Clone + 'static,
              C2: Debug + Send + Sync + Clone + 'static,
    {
        let e = self.next_entity();
        self.entities.push(e.clone());
        self.current_events.channels.push(RwLock::new(Vec::new()));
        self.next_events.channels.push(RwLock::new(Vec::new()));

        {
            let nc: &mut VecResource<C1> = self.next_components.entry().or_insert_with(VecResource::new);
            nc.data.push(component1.clone());
            let components: &mut VecResource<C1> = self.current_components.entry().or_insert_with(VecResource::new);
            components.data.push(component1);
        }
        {
            let nc: &mut VecResource<C2> = self.next_components.entry().or_insert_with(VecResource::new);
            nc.data.push(component2.clone());
            let components: &mut VecResource<C2> = self.current_components.entry().or_insert_with(VecResource::new);
            components.data.push(component2);
        }

        e
    }

    /*
Uninitialized components makes this tricky,
as does making sure we register all component types
before adding them.
Not impossible, just takes a little finesse.
How does specs do it?
    fn add_component<C>(&mut self, entity: Entity, component: C)
        where C: Debug + Send + Sync + Clone + 'static {
        let nc: &mut VecResource<T> = self.next_components.entry().or_insert_with(VecResource::new);
        nc.data.push(component.clone());
        let components: &mut VecResource<T> = self.current_components.entry().or_insert_with(VecResource::new);
        components.data.push(component);
    }
*/

    fn send_to_entity(&mut self, entity: Entity, event: E) {
        self.next_events.send_to_entity(entity, event);
    }
}

#[cfg(test)]
mod tests {

    use super::*;
    use rand;

    #[test]
    fn test_world_thingy() {
        let entity_count = 100;
        let message_count = 1000;
        let loops = 100;
        let mut w = World::new();
        for i in 0..entity_count {
            w.create_entity(i as usize, ());
        }
        for i in 0..message_count {
            let dest = rand::random::<u32>() % (entity_count as u32);
            w.send_to_entity(Entity(dest), 0);
        }
        for _ in 0..loops {
            // Call finish to make the event routing happen.
            w.finish();
            w.run1(|comp: &usize, events: &[usize], writer: &EventSender<usize>| {
                // println!("Component: {} Event: {:?}", comp, events);
                // Just send any event you get to the next entity index;
                // the event number is how many times it's been sent.
                for e in events {
                    writer.send_to_entity(Entity(((*comp+1) % entity_count) as u32), *e + 1);
                }
                *comp
            });
            //println!("Entit are {:?}", results);
        }
        let mut desired_results: Vec<u32> = Vec::new();
        desired_results.extend(&[2, 3, 4, 5, 6, 7, 8, 9, 10, 11][..]);
        assert!(false);
    }
}
<commit_msg>Making ECS functions public<commit_after>use std::fmt::Debug;
use std::mem;
use std::sync::mpsc;
use std::sync::RwLock;

use rayon::prelude::*;
use rayon;
use anymap;

#[derive(Clone, Default, Debug)]
pub struct Component {
    data: i32,
}

// #[derive(Clone, Default)]
// pub struct VecResource<T> {
//     data: Vec<T>,
// }

#[derive(Clone, Default, Debug)]
pub struct VecResource<T>
    where T: Debug
{
    data: Vec<T>,
}

impl<T> VecResource<T>
    where T: Debug
{
    pub fn new() -> Self {
        VecResource { data: Vec::new() }
    }
}

#[derive(Clone, Debug)]
pub struct Entity(u32);

pub type InputChannel<T> = Vec<T>;
pub type OutputChannel<T> = mpsc::Sender<T>;

pub struct EventSender<E> {
    channels: Vec<RwLock<Vec<E>>>
}

// We never clone the channel senders, so I'm not sure if this is
// really better than just having a Vec<RwLock<E>>, but...
impl<E> EventSender<E> where E: Send + Sync {
    fn new() -> Self {
        EventSender {
            channels: Vec::new(),
        }
    }

    pub fn send_to_entity(&self, entity: Entity, event: E) {
        let channel = self.channels.get(entity.0 as usize).expect("Sent message to non-existent entity!");
        let channel_write = &mut channel.write().expect("Attempted to write on poisoned RwLock, aiee!");
        channel_write.push(event);
    }

    pub fn clear(&mut self) {
        // Might as well parallelize?
        // Overhead might not make it worth it.
        // Try it later, see if it matters.

        self.channels.par_iter()
            .for_each(|q| {
                // Not sure if this is actually an optimization but it might be?
                // Depends on how expensive getting a write lock is.
                // ...Probably not more expensive than getting a read lock, tbh.
                let to_clear = {
                    let q_read = &mut q.try_read().unwrap();
                    q_read.len() > 0
                };
                if to_clear {
                    let q_write = &mut q.try_write().expect("Tried to clear event queues while in use; should never happen!");
                    q_write.clear();
                }
            });
    }
}

// I feel a little ghetto making one global event type for everything,
// but we'll roll with it for now.
pub struct World<E> where E: Send {
    entities: Vec<Entity>,
    current_components: anymap::AnyMap,
    next_components: anymap::AnyMap,
    current_events: EventSender<E>,
    next_events: EventSender<E>,
}

impl<E> World<E> where E: Send + Sync {
    pub fn new() -> Self {
        World {
            entities: Vec::new(),
            current_components: anymap::AnyMap::new(),
            next_components: anymap::AnyMap::new(),
            current_events: EventSender::new(),
            next_events: EventSender::new(),
        }
    }

    pub fn register<T>(&mut self)
        where T: Default + 'static
    {
        self.current_components.insert(T::default());
        self.next_components.insert(T::default());
    }

    pub fn run1<F, C>(&mut self, f: F)
        where F: Fn(&C, &[E], &EventSender<E>) -> C + Sync,
              C: Debug + Send + Sync + 'static
    {
        if let Some(resource) = self.current_components.get::<VecResource<C>>() {
            if let Some(next_components) = self.next_components.get_mut::<VecResource<C>>() {
                let d: &[C] = &resource.data;
                let v = &mut next_components.data;
                let next_events = &self.next_events;
                d.par_iter()
                    .zip(&self.current_events.channels)
                    .map(|(c, e)| {
                        let event_queue = e.read().expect("Aiee event queue is poisoned in World::run()");
                        f(c, &event_queue[..], next_events)
                    })
                    .collect_into(v);
            } else {
                panic!("current_components exists but next_components does not, this should never happen!")
            }
        } else {
            panic!("Tried to run a system on an unknown component type");
        }
    }

    pub fn run2<F, C1, C2>(&mut self, f: F)
        where F: Fn(&C1, &C2, &[E], &EventSender<E>) -> (C1, C2) + Sync,
              C1: Debug + Send + Sync + 'static,
              C2: Debug + Send + Sync + 'static
    {
        let current1 = self.current_components.get::<VecResource<C1>>().expect("Tried to run a system on an unknown component type");
        let current2 = self.current_components.get::<VecResource<C2>>().expect("Tried to run a system on an unknown component type");
        let c1: &[C1] = &current1.data;
        let c2: &[C2] = &current2.data;

        let next_events = &self.next_events;
        // BUGGO: Aieee, my perfect non-allocating system is now poisoned!
        let mut next_hax: Vec<(C1, C2)> = Vec::with_capacity(c1.len());
        c1.par_iter()
            .zip(c2)
            .zip(&self.current_events.channels)
            .map(|((comp1, comp2), e)| {
                let event_queue = e.read().expect("Aiee event queue is poisoned in World::run(); did a system crash?");
                f(comp1, comp2, &event_queue[..], next_events)
            })
            .collect_into(&mut next_hax);
        //.enumerate()
        // This doesn't seem to work 'cause it gets pesky about the closure altering self,
        // for some reason.  Hmm.
        //.for_each(|(i, (comp1, comp2))| {
            //    next1.data[i] = comp1;
            //});
        //.collect_into(v);
        let (r1, r2): (Vec<C1>, Vec<C2>) = next_hax.into_iter().unzip();
        {
            let next1 = self.next_components.get_mut::<VecResource<C1>>().expect("current_components exists but next_components does not, this should never happen!");
            let n1 = &mut next1.data;
            *n1 = r1;
        }
        {
            let next2 = self.next_components.get_mut::<VecResource<C2>>().expect("current_components exists but next_components does not, this should never happen!");
            let n2 = &mut next2.data;
            *n2 = r2;
        }
    }

    // This function finalizes the end of the frame.
    // Delivers events, flips the current and next components, etc.
    pub fn finish(&mut self) {
        // Switch components
        {
            let m1 = &mut self.current_components;
            let m2 = &mut self.next_components;
            mem::swap(m1, m2);
        }

        // empty out old events, deliver new ones.
        // Making the iterator work easily takes a little
        // bit of explicit type-mongling
        {
            let e1 = &mut self.current_events;
            let e2 = &mut self.next_events;
            mem::swap(e1, e2);
        }
        self.next_events.clear();
    }

    fn next_entity(&self) -> Entity {
        use std::u32;
        assert!(self.entities.len() < u32::MAX as usize);
        Entity(self.entities.len() as u32)
    }

    pub fn create_entity<C1, C2>(&mut self, component1: C1, component2: C2) -> Entity
        where C1: Debug + Send + Sync + Clone + 'static,
              C2: Debug + Send + Sync + Clone + 'static,
    {
        let e = self.next_entity();
        self.entities.push(e.clone());
        self.current_events.channels.push(RwLock::new(Vec::new()));
        self.next_events.channels.push(RwLock::new(Vec::new()));

        {
            let nc: &mut VecResource<C1> = self.next_components.entry().or_insert_with(VecResource::new);
            nc.data.push(component1.clone());
            let components: &mut VecResource<C1> = self.current_components.entry().or_insert_with(VecResource::new);
            components.data.push(component1);
        }
        {
            let nc: &mut VecResource<C2> = self.next_components.entry().or_insert_with(VecResource::new);
            nc.data.push(component2.clone());
            let components: &mut VecResource<C2> = self.current_components.entry().or_insert_with(VecResource::new);
            components.data.push(component2);
        }

        e
    }

    /*
Uninitialized components makes this tricky,
as does making sure we register all component types
before adding them.
Not impossible, just takes a little finesse.
How does specs do it?
    fn add_component<C>(&mut self, entity: Entity, component: C)
        where C: Debug + Send + Sync + Clone + 'static {
        let nc: &mut VecResource<T> = self.next_components.entry().or_insert_with(VecResource::new);
        nc.data.push(component.clone());
        let components: &mut VecResource<T> = self.current_components.entry().or_insert_with(VecResource::new);
        components.data.push(component);
    }
*/

    pub fn send_to_entity(&mut self, entity: Entity, event: E) {
        self.next_events.send_to_entity(entity, event);
    }
}

#[cfg(test)]
mod tests {

    use super::*;
    use rand;

    #[test]
    fn test_world_thingy() {
        let entity_count = 100;
        let message_count = 1000;
        let loops = 100;
        let mut w = World::new();
        for i in 0..entity_count {
            w.create_entity(i as usize, ());
        }
        for i in 0..message_count {
            let dest = rand::random::<u32>() % (entity_count as u32);
            w.send_to_entity(Entity(dest), 0);
        }
        for _ in 0..loops {
            // Call finish to make the event routing happen.
            w.finish();
            w.run1(|comp: &usize, events: &[usize], writer: &EventSender<usize>| {
                // println!("Component: {} Event: {:?}", comp, events);
                // Just send any event you get to the next entity index;
                // the event number is how many times it's been sent.
                for e in events {
                    writer.send_to_entity(Entity(((*comp+1) % entity_count) as u32), *e + 1);
                }
                *comp
            });
            //println!("Entit are {:?}", results);
        }
        let mut desired_results: Vec<u32> = Vec::new();
        desired_results.extend(&[2, 3, 4, 5, 6, 7, 8, 9, 10, 11][..]);
        assert!(false);
    }
}
<|endoftext|>


<commit_before>#[macro_export]
macro_rules! syslog {
    ($level:path, $msg:expr) => (
        unsafe {
            libc::openlog("sectora".as_ptr() as *const i8, libc::LOG_PID, libc::LOG_AUTH);
            libc::syslog($level, $msg.as_ptr() as *const i8);
            libc::closelog();
        }
    )
}
<commit_msg>Fix pointer types<commit_after>#[macro_export]
macro_rules! syslog {
    ($level:path, $msg:expr) => (
        unsafe {
            libc::openlog("sectora".as_ptr() as *const libc::c_char, libc::LOG_PID, libc::LOG_AUTH);
            libc::syslog($level, $msg.as_ptr() as *const libc::c_char);
            libc::closelog();
        }
    )
}
<|endoftext|>


<commit_before>//
// Sysinfo
//
// Copyright (c) 2015 Guillaume Gomez
//

// Once https://github.com/rust-lang/rfcs/blob/master/text/1422-pub-restricted.md
// feature gets stabilized, we can move common parts in here.

#[cfg(test)]
mod tests {
    use ::{ProcessExt, System, SystemExt};
    use ::utils;

    #[test]
    fn test_refresh_system() {
        let mut sys = System::new();
        sys.refresh_system();
        assert!(sys.get_total_memory() != 0);
        assert!(sys.get_free_memory() != 0);
        assert!(sys.get_total_memory() >= sys.get_free_memory());
        assert!(sys.get_total_swap() >= sys.get_free_swap());
    }

    #[test]
    fn test_refresh_process() {
        let mut sys = System::new();
        assert!(sys.refresh_process(utils::get_current_pid()));
    }

    #[test]
    fn test_get_process() {
        let mut sys = System::new();
        sys.refresh_processes();
        let p = sys.get_process(utils::get_current_pid()).expect("didn't find process");
        assert!(p.memory() > 0);
    }
}
<commit_msg>Add test to check if Process implements Send and Sync traits<commit_after>//
// Sysinfo
//
// Copyright (c) 2015 Guillaume Gomez
//

// Once https://github.com/rust-lang/rfcs/blob/master/text/1422-pub-restricted.md
// feature gets stabilized, we can move common parts in here.

#[cfg(test)]
mod tests {
    use ::{ProcessExt, System, SystemExt};
    use ::utils;

    #[test]
    fn test_refresh_system() {
        let mut sys = System::new();
        sys.refresh_system();
        assert!(sys.get_total_memory() != 0);
        assert!(sys.get_free_memory() != 0);
        assert!(sys.get_total_memory() >= sys.get_free_memory());
        assert!(sys.get_total_swap() >= sys.get_free_swap());
    }

    #[test]
    fn test_refresh_process() {
        let mut sys = System::new();
        assert!(sys.refresh_process(utils::get_current_pid()));
    }

    #[test]
    fn test_get_process() {
        let mut sys = System::new();
        sys.refresh_processes();
        let p = sys.get_process(utils::get_current_pid()).expect("didn't find process");
        assert!(p.memory() > 0);
    }

    #[test]
    fn check_if_send_and_sync() {
        trait Foo {
            fn foo(&self) {}
        }
        impl<T> Foo for T where T: Send {}

        trait Bar {
            fn bar(&self) {}
        }

        impl<T> Bar for T where T: Sync {}

        let mut sys = System::new();
        sys.refresh_processes();
        let p = sys.get_process(utils::get_current_pid()).expect("didn't find process");
        p.foo(); // If this doesn't compile, it'll simply mean that the Process type
                 // doesn't implement the Send trait.
        p.bar(); // If this doesn't compile, it'll simply mean that the Process type
                 // doesn't implement the Sync trait.
    }
}
<|endoftext|>


<commit_before>//! This modules contains an implementation of [r2d2](https://github.com/sfackler/r2d2)
//! functionality of connection pools. To get more details about creating r2d2 pools
//! please refer to original documentation.
use std::iter::Iterator;
use query::QueryBuilder;
use client::{CDRS, Session};
use error::{Error as CError, Result as CResult};
use authenticators::Authenticator;
use compression::Compression;
use r2d2;
use transport::CDRSTransport;
use rand;
use std::sync::atomic::{AtomicUsize, Ordering};

/// Load balancing strategy
#[derive(PartialEq)]
pub enum LoadBalancingStrategy {
    /// Round Robin balancing strategy
    RoundRobin,
    /// Random balancing strategy
    Random,
}

impl LoadBalancingStrategy {
    /// Returns next value for selected load balancing strategy
    pub fn next<'a, N>(&'a self, nodes: &'a Vec<N>, i: usize) -> Option<&N> {
        println!("node# {:?}", i);
        match *self {
            LoadBalancingStrategy::Random => nodes.get(self.rnd_idx((0, Some(nodes.len())))),
            LoadBalancingStrategy::RoundRobin => {
                let mut cycle = nodes.iter().cycle().skip(i);
                cycle.next()
            }
        }
    }

    /// Returns random number from a range
    fn rnd_idx(&self, bounds: (usize, Option<usize>)) -> usize {
        let min = bounds.0;
        let max = bounds.1.unwrap_or(u8::max_value() as usize);
        let rnd = rand::random::<usize>();
        min + rnd * (max - min) / (u8::max_value() as usize)
    }
}

/// Load balancer
///
/// #Example
///
/// ```no_run
/// use cdrs::cluster::{LoadBalancingStrategy, LoadBalancer};
/// use cdrs::transport::TransportTcp;
/// let transports = vec![TransportTcp::new("127.0.0.1:9042"), TransportTcp::new("127.0.0.1:9042")];
/// let load_balancer = LoadBalancer::new(transports, LoadBalancingStrategy::RoundRobin);
/// let node = load_balancer.next().unwrap();
/// ```
pub struct LoadBalancer<T> {
    strategy: LoadBalancingStrategy,
    nodes: Vec<T>,
    i: AtomicUsize,
}

impl<T> LoadBalancer<T> {
    /// Factory function which creates new `LoadBalancer` with provided strategy.
    pub fn new(nodes: Vec<T>, strategy: LoadBalancingStrategy) -> LoadBalancer<T> {
        LoadBalancer {
            nodes: nodes,
            strategy: strategy,
            i: AtomicUsize::new(0),
        }
    }

    /// Returns next node basing on provided strategy.
    pub fn next(&self) -> Option<&T> {
        let next = self.strategy
            .next(&self.nodes, self.i.load(Ordering::Relaxed) as usize);
        if self.strategy == LoadBalancingStrategy::RoundRobin {
            self.i.fetch_add(1, Ordering::Relaxed);
            // prevent overflow
            let i = self.i.load(Ordering::Relaxed);
            match i.checked_rem(self.nodes.len() as usize) {
                Some(rem) => self.i.store(rem, Ordering::Relaxed),
                None => return None,
            }
        }
        next
    }
}

/// [r2d2](https://github.com/sfackler/r2d2) `ManageConnection`.
pub struct ClusterConnectionManager<T, X> {
    load_balancer: LoadBalancer<X>,
    authenticator: T,
    compression: Compression,
}

impl<T, X> ClusterConnectionManager<T, X>
    where T: Authenticator + Send + Sync + 'static
{
    /// Creates a new instance of `ConnectionManager`.
    /// It requires transport, authenticator and compression as inputs.
    pub fn new(load_balancer: LoadBalancer<X>,
               authenticator: T,
               compression: Compression)
               -> ClusterConnectionManager<T, X> {
        ClusterConnectionManager {
            load_balancer: load_balancer,
            authenticator: authenticator,
            compression: compression,
        }
    }
}

impl<T: Authenticator + Send + Sync + 'static, X: CDRSTransport + Send + Sync + 'static>
r2d2::ManageConnection for ClusterConnectionManager<T, X> {
    type Connection = Session<T,X>;
    type Error = CError;

    fn connect(&self) -> Result<Self::Connection, Self::Error> {
        let transport_res: CResult<X> = self.load_balancer.next()
            .ok_or_else(|| "Cannot get next node".into())
            .and_then(|x| x.try_clone().map_err(|e| e.into()));
        let transport = try!(transport_res);
        let compression = self.compression;
        let cdrs = CDRS::new(transport, self.authenticator.clone());

        cdrs.start(compression)
    }

    fn is_valid(&self, connection: &mut Self::Connection) -> Result<(), Self::Error> {
        let query = QueryBuilder::new("SELECT * FROM system.peers;").finalize();

        connection.query(query, false, false).map(|_| ())
    }

    fn has_broken(&self, _connection: &mut Self::Connection) -> bool {
        false
    }
}

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

    #[test]
    fn round_robin() {
        let nodes = vec!["a", "b", "c"];
        let nodes_c = nodes.clone();
        let load_balancer = LoadBalancer::new(nodes, LoadBalancingStrategy::RoundRobin);
        for i in 0..10 {
            assert_eq!(&nodes_c[i % 3], load_balancer.next().unwrap());
        }
    }
}
<commit_msg>Remove stray println from cluster manager<commit_after>//! This modules contains an implementation of [r2d2](https://github.com/sfackler/r2d2)
//! functionality of connection pools. To get more details about creating r2d2 pools
//! please refer to original documentation.
use std::iter::Iterator;
use query::QueryBuilder;
use client::{CDRS, Session};
use error::{Error as CError, Result as CResult};
use authenticators::Authenticator;
use compression::Compression;
use r2d2;
use transport::CDRSTransport;
use rand;
use std::sync::atomic::{AtomicUsize, Ordering};

/// Load balancing strategy
#[derive(PartialEq)]
pub enum LoadBalancingStrategy {
    /// Round Robin balancing strategy
    RoundRobin,
    /// Random balancing strategy
    Random,
}

impl LoadBalancingStrategy {
    /// Returns next value for selected load balancing strategy
    pub fn next<'a, N>(&'a self, nodes: &'a Vec<N>, i: usize) -> Option<&N> {
        match *self {
            LoadBalancingStrategy::Random => nodes.get(self.rnd_idx((0, Some(nodes.len())))),
            LoadBalancingStrategy::RoundRobin => {
                let mut cycle = nodes.iter().cycle().skip(i);
                cycle.next()
            }
        }
    }

    /// Returns random number from a range
    fn rnd_idx(&self, bounds: (usize, Option<usize>)) -> usize {
        let min = bounds.0;
        let max = bounds.1.unwrap_or(u8::max_value() as usize);
        let rnd = rand::random::<usize>();
        min + rnd * (max - min) / (u8::max_value() as usize)
    }
}

/// Load balancer
///
/// #Example
///
/// ```no_run
/// use cdrs::cluster::{LoadBalancingStrategy, LoadBalancer};
/// use cdrs::transport::TransportTcp;
/// let transports = vec![TransportTcp::new("127.0.0.1:9042"), TransportTcp::new("127.0.0.1:9042")];
/// let load_balancer = LoadBalancer::new(transports, LoadBalancingStrategy::RoundRobin);
/// let node = load_balancer.next().unwrap();
/// ```
pub struct LoadBalancer<T> {
    strategy: LoadBalancingStrategy,
    nodes: Vec<T>,
    i: AtomicUsize,
}

impl<T> LoadBalancer<T> {
    /// Factory function which creates new `LoadBalancer` with provided strategy.
    pub fn new(nodes: Vec<T>, strategy: LoadBalancingStrategy) -> LoadBalancer<T> {
        LoadBalancer {
            nodes: nodes,
            strategy: strategy,
            i: AtomicUsize::new(0),
        }
    }

    /// Returns next node basing on provided strategy.
    pub fn next(&self) -> Option<&T> {
        let next = self.strategy
            .next(&self.nodes, self.i.load(Ordering::Relaxed) as usize);
        if self.strategy == LoadBalancingStrategy::RoundRobin {
            self.i.fetch_add(1, Ordering::Relaxed);
            // prevent overflow
            let i = self.i.load(Ordering::Relaxed);
            match i.checked_rem(self.nodes.len() as usize) {
                Some(rem) => self.i.store(rem, Ordering::Relaxed),
                None => return None,
            }
        }
        next
    }
}

/// [r2d2](https://github.com/sfackler/r2d2) `ManageConnection`.
pub struct ClusterConnectionManager<T, X> {
    load_balancer: LoadBalancer<X>,
    authenticator: T,
    compression: Compression,
}

impl<T, X> ClusterConnectionManager<T, X>
    where T: Authenticator + Send + Sync + 'static
{
    /// Creates a new instance of `ConnectionManager`.
    /// It requires transport, authenticator and compression as inputs.
    pub fn new(load_balancer: LoadBalancer<X>,
               authenticator: T,
               compression: Compression)
               -> ClusterConnectionManager<T, X> {
        ClusterConnectionManager {
            load_balancer: load_balancer,
            authenticator: authenticator,
            compression: compression,
        }
    }
}

impl<T: Authenticator + Send + Sync + 'static, X: CDRSTransport + Send + Sync + 'static>
r2d2::ManageConnection for ClusterConnectionManager<T, X> {
    type Connection = Session<T,X>;
    type Error = CError;

    fn connect(&self) -> Result<Self::Connection, Self::Error> {
        let transport_res: CResult<X> = self.load_balancer.next()
            .ok_or_else(|| "Cannot get next node".into())
            .and_then(|x| x.try_clone().map_err(|e| e.into()));
        let transport = try!(transport_res);
        let compression = self.compression;
        let cdrs = CDRS::new(transport, self.authenticator.clone());

        cdrs.start(compression)
    }

    fn is_valid(&self, connection: &mut Self::Connection) -> Result<(), Self::Error> {
        let query = QueryBuilder::new("SELECT * FROM system.peers;").finalize();

        connection.query(query, false, false).map(|_| ())
    }

    fn has_broken(&self, _connection: &mut Self::Connection) -> bool {
        false
    }
}

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

    #[test]
    fn round_robin() {
        let nodes = vec!["a", "b", "c"];
        let nodes_c = nodes.clone();
        let load_balancer = LoadBalancer::new(nodes, LoadBalancingStrategy::RoundRobin);
        for i in 0..10 {
            assert_eq!(&nodes_c[i % 3], load_balancer.next().unwrap());
        }
    }
}
<|endoftext|>


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

#![allow(unsafe_code)]

//! An implementation of `RocksDB` database.

pub use exonum_rocksdb::{
    BlockBasedOptions as RocksBlockOptions, WriteOptions as RocksDBWriteOptions,
};

use std::{error::Error, fmt, iter::Peekable, mem, path::Path, sync::Arc};

use exonum_rocksdb::{
    self, utils::get_cf_names, DBIterator, Options as RocksDbOptions, WriteBatch,
};

use crate::{db::Change, Database, DbOptions, Iter, Iterator, Patch, Snapshot};

impl From<exonum_rocksdb::Error> for crate::Error {
    fn from(err: exonum_rocksdb::Error) -> Self {
        Self::new(err.description())
    }
}

/// Database implementation on top of [`RocksDB`](https://rocksdb.org)
/// backend.
///
/// `RocksDB` is an embedded database for key-value data, which is optimized for fast storage.
/// This structure is required to potentially adapt the interface to
/// use different databases.
pub struct RocksDB {
    db: Arc<exonum_rocksdb::DB>,
}

impl DbOptions {
    fn to_rocksdb(&self) -> RocksDbOptions {
        let mut defaults = RocksDbOptions::default();
        defaults.create_if_missing(self.create_if_missing);
        defaults.set_max_open_files(self.max_open_files.unwrap_or(-1));
        defaults
    }
}

/// A snapshot of a `RocksDB`.
pub struct RocksDBSnapshot {
    snapshot: exonum_rocksdb::Snapshot<'static>,
    db: Arc<exonum_rocksdb::DB>,
}

/// An iterator over the entries of a `RocksDB`.
struct RocksDBIterator {
    iter: Peekable<DBIterator>,
    key: Option<Box<[u8]>>,
    value: Option<Box<[u8]>>,
}

impl RocksDB {
    /// Opens a database stored at the specified path with the specified options.
    ///
    /// If the database does not exist at the indicated path and the option
    /// `create_if_missing` is switched on in `DbOptions`, a new database will
    /// be created at the indicated path.
    pub fn open<P: AsRef<Path>>(path: P, options: &DbOptions) -> crate::Result<Self> {
        let db = {
            if let Ok(names) = get_cf_names(&path) {
                let cf_names = names.iter().map(|name| name.as_str()).collect::<Vec<_>>();
                exonum_rocksdb::DB::open_cf(&options.to_rocksdb(), path, cf_names.as_ref())?
            } else {
                exonum_rocksdb::DB::open(&options.to_rocksdb(), path)?
            }
        };
        Ok(Self { db: Arc::new(db) })
    }

    fn do_merge(&self, patch: Patch, w_opts: &RocksDBWriteOptions) -> crate::Result<()> {
        let mut batch = WriteBatch::default();
        for (cf_name, changes) in patch {
            let cf = match self.db.cf_handle(&cf_name) {
                Some(cf) => cf,
                None => self
                    .db
                    .create_cf(&cf_name, &DbOptions::default().to_rocksdb())
                    .unwrap(),
            };
            for (key, change) in changes {
                match change {
                    Change::Put(ref value) => batch.put_cf(cf, key.as_ref(), value)?,
                    Change::Delete => batch.delete_cf(cf, &key)?,
                }
            }
        }
        self.db.write_opt(batch, w_opts).map_err(Into::into)
    }
}

impl Database for RocksDB {
    fn snapshot(&self) -> Box<dyn Snapshot> {
        Box::new(RocksDBSnapshot {
            snapshot: unsafe { mem::transmute(self.db.snapshot()) },
            db: Arc::clone(&self.db),
        })
    }

    fn merge(&self, patch: Patch) -> crate::Result<()> {
        let w_opts = RocksDBWriteOptions::default();
        self.do_merge(patch, &w_opts)
    }

    fn merge_sync(&self, patch: Patch) -> crate::Result<()> {
        let mut w_opts = RocksDBWriteOptions::default();
        w_opts.set_sync(true);
        self.do_merge(patch, &w_opts)
    }
}

impl Snapshot for RocksDBSnapshot {
    fn get(&self, name: &str, key: &[u8]) -> Option<Vec<u8>> {
        if let Some(cf) = self.db.cf_handle(name) {
            match self.snapshot.get_cf(cf, key) {
                Ok(value) => value.map(|v| v.to_vec()),
                Err(e) => panic!(e),
            }
        } else {
            None
        }
    }

    fn iter<'a>(&'a self, name: &str, from: &[u8]) -> Iter<'a> {
        use exonum_rocksdb::{Direction, IteratorMode};
        let iter = match self.db.cf_handle(name) {
            Some(cf) => self
                .snapshot
                .iterator_cf(cf, IteratorMode::From(from, Direction::Forward))
                .unwrap(),
            None => self.snapshot.iterator(IteratorMode::Start),
        };
        Box::new(RocksDBIterator {
            iter: iter.peekable(),
            key: None,
            value: None,
        })
    }
}

impl Iterator for RocksDBIterator {
    fn next(&mut self) -> Option<(&[u8], &[u8])> {
        if let Some((key, value)) = self.iter.next() {
            self.key = Some(key);
            self.value = Some(value);
            Some((self.key.as_ref().unwrap(), self.value.as_ref().unwrap()))
        } else {
            None
        }
    }

    fn peek(&mut self) -> Option<(&[u8], &[u8])> {
        if let Some(&(ref key, ref value)) = self.iter.peek() {
            Some((key, value))
        } else {
            None
        }
    }
}

impl From<RocksDB> for Arc<dyn Database> {
    fn from(db: RocksDB) -> Self {
        Self::from(Box::new(db) as Box<dyn Database>)
    }
}

impl fmt::Debug for RocksDB {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "RocksDB(..)")
    }
}

impl fmt::Debug for RocksDBSnapshot {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "RocksDBSnapshot(..)")
    }
}
<commit_msg>Some small code polishing<commit_after>// Copyright 2018 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![allow(unsafe_code)]

//! An implementation of `RocksDB` database.

pub use exonum_rocksdb::{
    BlockBasedOptions as RocksBlockOptions, WriteOptions as RocksDBWriteOptions,
};

use std::{error::Error, fmt, iter::Peekable, mem, path::Path, sync::Arc};

use exonum_rocksdb::{
    self, utils::get_cf_names, DBIterator, Options as RocksDbOptions, WriteBatch,
};

use crate::{db::Change, Database, DbOptions, Iter, Iterator, Patch, Snapshot};

impl From<exonum_rocksdb::Error> for crate::Error {
    fn from(err: exonum_rocksdb::Error) -> Self {
        Self::new(err.description())
    }
}

/// Database implementation on top of [`RocksDB`](https://rocksdb.org)
/// backend.
///
/// `RocksDB` is an embedded database for key-value data, which is optimized for fast storage.
/// This structure is required to potentially adapt the interface to
/// use different databases.
pub struct RocksDB {
    db: Arc<exonum_rocksdb::DB>,
}

impl From<DbOptions> for RocksDbOptions {
    fn from(opts: DbOptions) -> Self {
        Self::from(&opts)
    }
}

impl From<&DbOptions> for RocksDbOptions {
    fn from(opts: &DbOptions) -> Self {
        let mut defaults = RocksDbOptions::default();
        defaults.create_if_missing(opts.create_if_missing);
        defaults.set_max_open_files(opts.max_open_files.unwrap_or(-1));
        defaults
    }
}

/// A snapshot of a `RocksDB`.
pub struct RocksDBSnapshot {
    snapshot: exonum_rocksdb::Snapshot<'static>,
    db: Arc<exonum_rocksdb::DB>,
}

/// An iterator over the entries of a `RocksDB`.
struct RocksDBIterator {
    iter: Peekable<DBIterator>,
    key: Option<Box<[u8]>>,
    value: Option<Box<[u8]>>,
}

impl RocksDB {
    /// Opens a database stored at the specified path with the specified options.
    ///
    /// If the database does not exist at the indicated path and the option
    /// `create_if_missing` is switched on in `DbOptions`, a new database will
    /// be created at the indicated path.
    pub fn open<P: AsRef<Path>>(path: P, options: &DbOptions) -> crate::Result<Self> {
        let db = {
            if let Ok(names) = get_cf_names(&path) {
                let cf_names = names.iter().map(|name| name.as_str()).collect::<Vec<_>>();
                exonum_rocksdb::DB::open_cf(&options.into(), path, cf_names.as_ref())?
            } else {
                exonum_rocksdb::DB::open(&options.into(), path)?
            }
        };
        Ok(Self { db: Arc::new(db) })
    }

    fn do_merge(&self, patch: Patch, w_opts: &RocksDBWriteOptions) -> crate::Result<()> {
        let mut batch = WriteBatch::default();
        for (cf_name, changes) in patch {
            let cf = match self.db.cf_handle(&cf_name) {
                Some(cf) => cf,
                None => self
                    .db
                    .create_cf(&cf_name, &DbOptions::default().into())
                    .unwrap(),
            };
            for (key, change) in changes {
                match change {
                    Change::Put(ref value) => batch.put_cf(cf, key.as_ref(), value)?,
                    Change::Delete => batch.delete_cf(cf, &key)?,
                }
            }
        }
        self.db.write_opt(batch, w_opts).map_err(Into::into)
    }
}

impl Database for RocksDB {
    fn snapshot(&self) -> Box<dyn Snapshot> {
        Box::new(RocksDBSnapshot {
            snapshot: unsafe { mem::transmute(self.db.snapshot()) },
            db: Arc::clone(&self.db),
        })
    }

    fn merge(&self, patch: Patch) -> crate::Result<()> {
        let w_opts = RocksDBWriteOptions::default();
        self.do_merge(patch, &w_opts)
    }

    fn merge_sync(&self, patch: Patch) -> crate::Result<()> {
        let mut w_opts = RocksDBWriteOptions::default();
        w_opts.set_sync(true);
        self.do_merge(patch, &w_opts)
    }
}

impl Snapshot for RocksDBSnapshot {
    fn get(&self, name: &str, key: &[u8]) -> Option<Vec<u8>> {
        if let Some(cf) = self.db.cf_handle(name) {
            match self.snapshot.get_cf(cf, key) {
                Ok(value) => value.map(|v| v.to_vec()),
                Err(e) => panic!(e),
            }
        } else {
            None
        }
    }

    fn iter<'a>(&'a self, name: &str, from: &[u8]) -> Iter<'a> {
        use exonum_rocksdb::{Direction, IteratorMode};
        let iter = match self.db.cf_handle(name) {
            Some(cf) => self
                .snapshot
                .iterator_cf(cf, IteratorMode::From(from, Direction::Forward))
                .unwrap(),
            None => self.snapshot.iterator(IteratorMode::Start),
        };
        Box::new(RocksDBIterator {
            iter: iter.peekable(),
            key: None,
            value: None,
        })
    }
}

impl Iterator for RocksDBIterator {
    fn next(&mut self) -> Option<(&[u8], &[u8])> {
        if let Some((key, value)) = self.iter.next() {
            self.key = Some(key);
            self.value = Some(value);
            Some((self.key.as_ref().unwrap(), self.value.as_ref().unwrap()))
        } else {
            None
        }
    }

    fn peek(&mut self) -> Option<(&[u8], &[u8])> {
        if let Some(&(ref key, ref value)) = self.iter.peek() {
            Some((key, value))
        } else {
            None
        }
    }
}

impl From<RocksDB> for Arc<dyn Database> {
    fn from(db: RocksDB) -> Self {
        Self::from(Box::new(db) as Box<dyn Database>)
    }
}

impl fmt::Debug for RocksDB {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "RocksDB(..)")
    }
}

impl fmt::Debug for RocksDBSnapshot {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "RocksDBSnapshot(..)")
    }
}
<|endoftext|>